Skip to content

fix: tolerate a null StandardChangeTemplateName from the server - #220

Open
susanpann wants to merge 4 commits into
mainfrom
susan/serviceNow
Open

fix: tolerate a null StandardChangeTemplateName from the server#220
susanpann wants to merge 4 commits into
mainfrom
susan/serviceNow

Conversation

@susanpann

@susanpann susanpann commented Nov 13, 2023

Copy link
Copy Markdown
Contributor

Relates to OctopusDeployLabs/terraform-provider-octopusdeploy#574

Changes direction from the original commit. The omitempty tags had no effect — ServiceNowExtensionSettings has a custom MarshalJSON that builds the Values map by hand and never reads struct tags, so the wire format was identical before and after.

Omitting the key isn't the fix either. The server stores Values verbatim and resolves the template with string.IsNullOrWhiteSpace, so an empty string already means "no standard change template". The portal reads Values.StandardChangeTemplateName.trim() unconditionally, so a project written without the key would break the ITSM settings page.

What actually breaks is reading a project whose value is null — UnmarshalJSON asserted straight to a string and panicked with interface conversion: interface {} is nil, not string. Values are now type-checked before assigning.

Three commits:

  1. ServiceNow — revert the no-op tags, type-check the four values in UnmarshalJSON.
  2. Jira Service Management — identical unchecked assertions, fixed the same way. A JSM project that isn't change controlled skips server-side validation, so a null ServiceDeskProjectName can be stored and panics on read.
  3. Test fix — TestJiraServiceManagementExtensionSettingsUnmarshalJSON built its input with ServiceNowExtensionID; nothing asserted the extension ID, so it went unnoticed.

Verified against a local instance for both extensions: a project with a null value panicked before and now reads back as empty, and a create/update/re-read round-trip is accepted and stable.

IsStateAutomaticallyTransitioned bool
StandardChangeTemplateName string
IsStateAutomaticallyTransitioned bool `json:"AutomaticStateTransition"`
StandardChangeTemplateName string `json:"StandardChangeTemplateName,omitempty"`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you describe how this relates to the issue?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if it's a required change, but I thought to add the omitempty to mimic what the UI does when sending the request. ie. If the standard template name isn't provided it leaves that field out of the request.

susanpann and others added 2 commits August 14, 2026 15:02
The struct tags added here had no effect: ServiceNowExtensionSettings has a
custom MarshalJSON that builds the Values map by hand and never consults them,
so the wire format was unchanged.

Omitting the key isn't the fix either. The server stores Values verbatim and
treats an empty StandardChangeTemplateName as "no standard change template",
so an empty string already works, and the portal reads the key back without
guarding against it being absent.

What does break is reading a project whose value is null, which UnmarshalJSON
asserted straight to a string and panicked on. Check the type instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@NickJosevski NickJosevski changed the title chore: omitempty standard change template fix: tolerate a null StandardChangeTemplateName from the server Aug 14, 2026
NickJosevski and others added 2 commits August 14, 2026 15:43
JiraServiceManagementExtensionSettings.UnmarshalJSON had the same unchecked
type assertions as the ServiceNow settings. A project that isn't change
controlled skips server-side validation entirely, so a null
ServiceDeskProjectName can be stored and panics on read.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The test built its input with extensions.ServiceNowExtensionID. Nothing
asserted the extension ID, so the mistake went unnoticed; assert it now.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants