gastownhall/beads · error

invalid dependency format %q, expected 'type:id' or 'id'

Error message

invalid dependency format %q, expected 'type:id' or 'id'

What it means

parseDepSpec parses each --deps entry as either a bare issue ID or "type:id" (single colon split). If the string contains a colon but splitting on the FIRST colon still fails to yield two parts — practically, an empty string that isn't a plain ID or malformed input like "::" or a lone ":" — this error fires. It tells you the expected grammar: 'type:id' or 'id'.

Source

Thrown at cmd/bd/create_deps.go:140

		if err != nil {
			return nil, fmt.Errorf("resolving --deps target %q: %w", target, err)
		}
		out[i].TargetID = resolved
	}
	return out, nil
}

func parseDepSpec(raw string) (domain.DependencySpec, error) {
	if !strings.Contains(raw, ":") {
		return domain.DependencySpec{
			Type:     types.DepBlocks,
			TargetID: raw,
		}, nil
	}

	parts := strings.SplitN(raw, ":", 2)
	if len(parts) != 2 {
		return domain.DependencySpec{}, fmt.Errorf("invalid dependency format %q, expected 'type:id' or 'id'", raw)
	}
	rawType := types.DependencyType(strings.TrimSpace(parts[0]))
	target := strings.TrimSpace(parts[1])

	spec := domain.DependencySpec{TargetID: target, Type: canonicalDependencyType(rawType)}
	if rawType == types.DepBlocks {
		// Explicit "blocks:" (as opposed to the "depends-on"/"blocked-by"
		// aliases, which keep direction) reverses direction: the target
		// depends on the issue being created, not the other way around.
		spec.SwapDirection = true
	}

	if err := validateDependencyType(spec.Type); err != nil {
		return domain.DependencySpec{}, err
	}
	return spec, nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Write each dep as either '<id>' or '<type>:<id>', e.g. "blocked-by:bd-3" or "bd-3"
  2. Check for doubled colons or wrong separators in your script's deps string
  3. Echo the composed --deps value before invoking bd to see the malformed entry

Example fix

// before
bd create "Task" --deps "blocked-by::bd-3"   # malformed
// after
bd create "Task" --deps "blocked-by:bd-3"
Defensive patterns

Strategy: validation

Validate before calling

func validDepSpec(s string) bool {
    s = strings.TrimSpace(s)
    if s == "" { return false }
    if !strings.Contains(s, ":") { return true } // bare id
    parts := strings.SplitN(s, ":", 2)
    return len(parts) == 2 && parts[0] != "" && parts[1] != ""
}

Prevention

When it happens

Trigger: `bd create ... --deps ":"` or `--deps "::bd-5"`-style malformed entries where SplitN(raw,":",2) does not return exactly 2 parts (e.g. raw is empty); also any spec string with unexpected formatting that slipped past the empty check.

Common situations: Hand-edited scripts with mangled separators (using '|' or ';' instead of ':'); accidentally passing an entire flag string as one dep; empty strings produced by aggressive shell splitting.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/b71e629ee4e66151. Report an issue: GitHub.