{"record":{"id":"fb06d5ca6a5b40a2","repo":"JuliusBrussee/caveman","slug":"systeminstruction-w","errorCode":null,"errorMessage":"systemInstruction: %w","messagePattern":"systemInstruction: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/pixel/transform_gemini.go","lineNumber":250,"sourceCode":"\tdef.EmitRecoverable = opts.EmitRecoverable\n\treturn def\n}\n\nfunc parseGeminiGenerateContent(body []byte) (geminiGenerateContent, error) {\n\tvar raw map[string]json.RawMessage\n\tif err := json.Unmarshal(body, &raw); err != nil {\n\t\treturn geminiGenerateContent{}, err\n\t}\n\treq := geminiGenerateContent{extra: raw}\n\tif v, ok := raw[\"contents\"]; ok {\n\t\tif err := json.Unmarshal(v, &req.Contents); err != nil {\n\t\t\treturn geminiGenerateContent{}, fmt.Errorf(\"contents: %w\", err)\n\t\t}\n\t}\n\tif v, ok := raw[\"systemInstruction\"]; ok && len(bytes.TrimSpace(v)) > 0 && !bytes.Equal(bytes.TrimSpace(v), []byte(\"null\")) {\n\t\tvar inst geminiInstruction\n\t\tif err := json.Unmarshal(v, &inst); err != nil {\n\t\t\treturn geminiGenerateContent{}, fmt.Errorf(\"systemInstruction: %w\", err)\n\t\t}\n\t\treq.SystemInstruction = &inst\n\t}\n\tif v, ok := raw[\"tools\"]; ok {\n\t\tif err := json.Unmarshal(v, &req.Tools); err != nil {\n\t\t\treturn geminiGenerateContent{}, fmt.Errorf(\"tools: %w\", err)\n\t\t}\n\t}\n\treturn req, nil\n}\n\nfunc geminiGlobalMediaResolution(raw map[string]json.RawMessage) (string, bool) {\n\tvar config json.RawMessage\n\tfor _, key := range []string{\"generationConfig\", \"generation_config\"} {\n\t\tif value, found := raw[key]; found {\n\t\t\tif config != nil {\n\t\t\t\treturn \"\", false\n\t\t\t}","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/engine/pixel/transform_gemini.go#L232-L268","documentation":"parseGeminiGenerateContent optionally unmarshals \"systemInstruction\" into a geminiInstruction when present, non-empty, and not literal null. If the value has the wrong shape (e.g. a bare string, or an object with unexpected field types), the unmarshal error is wrapped as \"systemInstruction: %w\" and TransformGemini fails.","triggerScenarios":"TransformGemini on a body where \"systemInstruction\" is present but not a valid instruction object — e.g. a plain string (some Gemini API variants accept string, this struct does not) or an object whose parts field has the wrong type.","commonSituations":"Clients built against a different Gemini API revision that sends systemInstruction as a string; templates that inject a raw string instead of {parts:[{text:...}]}; migrated prompts from other providers.","solutions":["Send systemInstruction as an object: {\"parts\":[{\"text\":\"...\"}]} rather than a bare string.","Read the wrapped error to identify which field type did not match.","If your SDK emits the string form, transform it to the parts-object form before calling TransformGemini."],"exampleFix":"// before\n{\"systemInstruction\": \"You are helpful.\"}\n// after\n{\"systemInstruction\": {\"parts\": [{\"text\": \"You are helpful.\"}]}}","handlingStrategy":"validation","validationCode":"var probe struct {\n    SystemInstruction *struct {\n        Parts []map[string]json.RawMessage `json:\"parts\"`\n    } `json:\"systemInstruction\"`\n}\nif err := json.Unmarshal(body, &probe); err != nil {\n    return fmt.Errorf(\"systemInstruction must be {parts:[{text:...}]}\")\n}","typeGuard":"func validSystemInstruction(raw map[string]json.RawMessage) bool {\n    v, ok := raw[\"systemInstruction\"]\n    if !ok || len(bytes.TrimSpace(v)) == 0 || bytes.Equal(bytes.TrimSpace(v), []byte(\"null\")) {\n        return true\n    }\n    var inst map[string]json.RawMessage\n    return json.Unmarshal(v, &inst) == nil && inst[\"parts\"] != nil\n}","tryCatchPattern":"req, err := parseGeminiGenerateContent(body)\nif err != nil {\n    if strings.Contains(err.Error(), \"systemInstruction:\") {\n        return fmt.Errorf(\"send systemInstruction as {parts:[{text:...}]}, not a bare string\")\n    }\n    return err\n}","preventionTips":["Always send systemInstruction as a parts-object, never a bare string.","Check which Gemini API revision your client targets; normalize the field before transforming.","Unwrap errors.As(*json.UnmarshalTypeError) to see the mismatched field name."],"tags":["gemini","json","request-transform","schema"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}