{"record":{"id":"53b07538f050478a","repo":"d2lang/d2","slug":"decode-diagram-hash-json-unexpected-delimiter-q","errorCode":null,"errorMessage":"decode diagram hash JSON: unexpected delimiter %q","messagePattern":"decode diagram hash JSON: unexpected delimiter %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"d2target/d2target.go","lineNumber":320,"sourceCode":"\t\t\t}\n\t\t\tif closeToken != json.Delim('}') {\n\t\t\t\treturn fmt.Errorf(\"decode diagram hash JSON: got closing token %v, want }\", closeToken)\n\t\t\t}\n\t\tcase '[':\n\t\t\tfor dec.More() {\n\t\t\t\tif err := walkValue(); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t\tcloseToken, err := dec.Token()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif closeToken != json.Delim(']') {\n\t\t\t\treturn fmt.Errorf(\"decode diagram hash JSON: got closing token %v, want ]\", closeToken)\n\t\t\t}\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"decode diagram hash JSON: unexpected delimiter %q\", delim)\n\t\t}\n\t\treturn nil\n\t}\n\n\tif err := walkValue(); err != nil {\n\t\treturn nil, err\n\t}\n\tout.Write(b[lastWrite:])\n\treturn out.Bytes(), nil\n}\n\nfunc hashJSONValueStart(b []byte, keyEnd int) (int, error) {\n\ti := keyEnd\n\tfor i < len(b) && (b[i] == ' ' || b[i] == '\\t' || b[i] == '\\r' || b[i] == '\\n') {\n\t\ti++\n\t}\n\tif i < len(b) && b[i] == ':' {\n\t\ti++","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/d2lang/d2/blob/0d69dca6f532ceaeacd615d35d1eaa41a238ffdb/d2target/d2target.go#L302-L338","documentation":"The stable-hash walker only expects '{', '[', or end-of-value tokens while descending. Any other delimiter token in the JSON stream hits the default branch and returns this error, naming the unexpected delimiter. It indicates the input is not structured as expected for canonicalization.","triggerScenarios":"Stable-hashing JSON that starts or contains a stray delimiter (e.g. a bare '}' or a token sequence the walker didn't anticipate), typically from non-JSON or corrupt input.","commonSituations":"Passing non-JSON data (YAML, raw text) to the hash function; corrupted cached diagram bytes; buggy custom JSON producers.","solutions":["Verify the input is valid JSON with json.Valid before calling the hash function","Re-generate the diagram JSON via d2graph/d2target serialization","Check the entry point: hash the serialized diagram, not the DSL source"],"exampleFix":"// before\nout, _ := StableHashWithIcons([]byte(dslSource)) // not JSON\n// after\nb, _ := json.Marshal(diagram)\nout, _ := StableHashWithIcons(b)","handlingStrategy":"validation","validationCode":"if !json.Valid(b) {\n\treturn errors.New(\"input to stable hash must be valid JSON\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Hash only serialized diagram JSON, never DSL source or other text","Validate JSON before hashing","Check file reads for truncation/corruption before hashing"],"tags":["json","hashing","structure"],"backgroundTag":"malformed-json-input","analyzedSha":"0d69dca6f532ceaeacd615d35d1eaa41a238ffdb","analyzedAt":"2026-08-31T12:19:21.182Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}