-
Notifications
You must be signed in to change notification settings - Fork 2k
Fix Gateway Job Spec marshaling #21695
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,7 +31,7 @@ type ProposeJobSpecInput struct { | |
| // Inputs is a map of input variables to be used in the job spec template. | ||
| // These will vary based on the template used, and will be validated differently | ||
| // for each template type. | ||
| Inputs job_types.JobSpecInput `json:"inputs" yaml:"inputs"` | ||
| Inputs *job_types.JobSpecInput `json:"inputs" yaml:"inputs"` | ||
| } | ||
|
|
||
| type ProposeJobSpec struct{} | ||
|
|
@@ -59,20 +59,20 @@ func (u ProposeJobSpec) VerifyPreconditions(_ cldf.Environment, config ProposeJo | |
|
|
||
| switch config.Template { | ||
| case job_types.EVM: | ||
| if err := verifyEVMJobSpecInputs(config.Inputs); err != nil { | ||
| if err := verifyEVMJobSpecInputs(*config.Inputs); err != nil { | ||
| return fmt.Errorf("invalid inputs for EVM job spec: %w", err) | ||
| } | ||
| case job_types.Solana: | ||
| if err := verifySolanaJobSpecInputs(config.Inputs); err != nil { | ||
| if err := verifySolanaJobSpecInputs(*config.Inputs); err != nil { | ||
| return fmt.Errorf("invalid inputs for EVM job spec: %w", err) | ||
|
Comment on lines
60
to
67
|
||
| } | ||
| case job_types.Cron, job_types.BootstrapOCR3, job_types.OCR3, job_types.Gateway, job_types.HTTPTrigger, job_types.HTTPAction, job_types.ConfidentialHTTP, job_types.BootstrapVault, job_types.Consensus, job_types.WebAPITrigger, job_types.WebAPITarget, job_types.CustomCompute, job_types.LogEventTrigger, job_types.ReadContract: | ||
| case job_types.CRESettings: | ||
| if err := verifyCRESettingsSpecInputs(config.Inputs); err != nil { | ||
| if err := verifyCRESettingsSpecInputs(*config.Inputs); err != nil { | ||
| return fmt.Errorf("invalid inputs for CRE settings job spec: %w", err) | ||
| } | ||
| case job_types.Ring: | ||
| if err := verifyRingJobSpecInputs(config.Inputs); err != nil { | ||
| if err := verifyRingJobSpecInputs(*config.Inputs); err != nil { | ||
| return fmt.Errorf("invalid inputs for Ring job spec: %w", err) | ||
| } | ||
| default: | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,33 +1,39 @@ | ||||||||||||||||||||||||||||
| package job_types | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||
| "encoding/json" | ||||||||||||||||||||||||||||
| "errors" | ||||||||||||||||||||||||||||
| "fmt" | ||||||||||||||||||||||||||||
| "strings" | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| "gopkg.in/yaml.v3" | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| "github.com/smartcontractkit/chainlink/deployment/cre/jobs/pkg" | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| type JobSpecInput map[string]any | ||||||||||||||||||||||||||||
| type JobSpecInput struct { | ||||||||||||||||||||||||||||
| json.RawMessage | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
Comment on lines
+12
to
+14
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Would this work too? |
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| func (j JobSpecInput) UnmarshalTo(target any) error { | ||||||||||||||||||||||||||||
| bytes, err := yaml.Marshal(j) | ||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||
| return fmt.Errorf("failed to marshal job spec input to json: %w", err) | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| func (j JobSpecInput) MarshalJSON() ([]byte, error) { | ||||||||||||||||||||||||||||
| return j.RawMessage.MarshalJSON() | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| func (j *JobSpecInput) UnmarshalJSON(d []byte) error { | ||||||||||||||||||||||||||||
| j.RawMessage = d | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
| j.RawMessage = d | |
| if d == nil { | |
| j.RawMessage = nil | |
| return nil | |
| } | |
| copied := make([]byte, len(d)) | |
| copy(copied, d) | |
| j.RawMessage = json.RawMessage(copied) |
Copilot
AI
Mar 25, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UnmarshalTo calls json.Unmarshal on j.RawMessage. When JobSpecInput is the zero value (RawMessage is nil/empty), json.Unmarshal returns "unexpected end of JSON input". If callers previously relied on an empty inputs object (or default/omitted inputs) being treated as an empty map, consider treating empty RawMessage as a no-op (or as {}) to preserve backwards-compatible behavior.
| return json.Unmarshal([]byte(j.RawMessage), target) | |
| // Treat empty or nil RawMessage as a no-op to preserve backward-compatible behavior | |
| // where omitted/empty inputs are interpreted as default/zero-valued targets. | |
| if len(j.RawMessage) == 0 { | |
| return nil | |
| } | |
| // Also treat explicit JSON null as a no-op for consistency with default semantics. | |
| if string(j.RawMessage) == "null" { | |
| return nil | |
| } | |
| return json.Unmarshal(j.RawMessage, target) |
Uh oh!
There was an error while loading. Please reload this page.