d2lang/d2 · error

decode icon URL for stable diagram hash: %w

Error message

decode icon URL for stable diagram hash: %w

What it means

When a JSON key equal to "icon" is found during stable hashing, the walker decodes its raw value to canonicalize the URL. If json.Decode of the raw value fails, this wrapped error is returned. It indicates the icon field's value cannot be decoded from the surrounding JSON stream.

Source

Thrown at d2target/d2target.go:281

				}
				key, ok := keyToken.(string)
				if !ok {
					return fmt.Errorf("decode diagram hash JSON: object key has type %T", keyToken)
				}
				if key != "icon" {
					if err := walkValue(); err != nil {
						return err
					}
					continue
				}

				valueStart, err := hashJSONValueStart(b, int(dec.InputOffset()))
				if err != nil {
					return err
				}
				var raw json.RawMessage
				if err := dec.Decode(&raw); err != nil {
					return fmt.Errorf("decode icon URL for stable diagram hash: %w", err)
				}
				if bytes.Equal(raw, []byte("null")) {
					continue
				}

				stable, err := stableHashURL(raw)
				if err != nil {
					return err
				}
				valueEnd := int(dec.InputOffset())
				if valueEnd < valueStart || valueEnd > len(b) {
					return fmt.Errorf("decode icon URL for stable diagram hash: invalid offsets %d:%d", valueStart, valueEnd)
				}
				out.Write(b[lastWrite:valueStart])
				out.Write(stable)
				lastWrite = valueEnd
			}
			closeToken, err := dec.Token()

View on GitHub (pinned to 0d69dca6f5)

Solutions

  1. Validate the JSON is well-formed with json.Valid before hashing
  2. Re-serialize the diagram from the in-memory d2target.Diagram
  3. Ensure the "icon" key holds a JSON string URL, not some other malformed value

Example fix

// before
hash, _ := StableHashWithIcons(brokenJSON)
// after
if !json.Valid(brokenJSON) { return errors.New("bad json") }
hash, _ := StableHashWithIcons(brokenJSON)
Defensive patterns

Strategy: validation

Validate before calling

if !json.Valid(b) {
	return errors.New("diagram JSON is malformed")
}

Try / catch

out, err := StableHashWithIcons(b)
if err != nil {
	// fallback: hash without icon canonicalization or re-marshal diagram
}

Prevention

When it happens

Trigger: Stable-hashing diagram JSON whose "icon" value sits at an invalid position in the stream (corrupt or truncated JSON), or JSON produced with encoding the decoder cannot handle at that offset.

Common situations: Manually edited diagram JSON; partial writes to cached diagram files; mixing JSON from incompatible d2 versions.

Related errors


AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31). Data as JSON: /api/errors/52a73c8fb65f5d5c. Report an issue: GitHub.