affaan-m/ECC · error · ValueError
invalid DID: (must start with 'did:')
Error message
invalid DID: {did!r} (must start with 'did:') What it means
aura_verdict validates that its `did` argument is a non-empty string starting with 'did:' before building the AURA check URL. If the DID is empty, None, or malformed, it raises ValueError("invalid DID: ... (must start with 'did:')") immediately — fail-fast input validation for the decentralized identifier format.
Solutions
- Ensure the DID is loaded/provisioned before calling — check the agent identity config or keychain entry exists
- Prefix raw keys with the scheme, e.g. 'z6Mk...' -> 'did:aura:z6Mk...'
- Trim whitespace/quotes around the configured DID value
- Validate the DID at config-load time so bad values fail before any settlement call
Example fix
# before
verdict = aura_verdict(agent_key) # 'z6Mk...'
# after
verdict = aura_verdict(f"did:aura:{agent_key}") if not agent_key.startswith("did:") else aura_verdict(agent_key) Defensive patterns
Strategy: validation
Validate before calling
def is_valid_did(did) -> bool:
return bool(did) and str(did).startswith("did:") Type guard
def require_did(did: str) -> str:
if not isinstance(did, str) or not did.startswith("did:"):
raise ValueError(f"invalid DID: {did!r}")
return did Try / catch
try:
v = aura_verdict(did)
except ValueError as e:
logger.error("bad DID configured: %s", e) # fail the workflow before settlement
raise Prevention
- Load and validate the DID at config/identity startup, not at call time
- Store DIDs with their did: scheme included; never strip it for storage
- Add a unit test asserting the identity module never returns an unprefixed key
When it happens
Trigger: Calling aura_verdict(None), aura_verdict(''), aura_verdict('z6Mk...') (raw key without did: prefix), or a non-string object; also via before_settle or the listed tests that pass an invalid DID.
Common situations: Agent identity not yet provisioned so the DID variable is None/empty; storing only the aura key (did:aura:z6Mk...) and stripping the scheme somewhere upstream; config loading returning the wrong field; tests passing placeholder values.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- application bundle differs from its bound evidence
- At least one video is required
- AuraUntrusted
- cannot upload, file does not exist
- Draft name must be a plain file name
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/829a5b49f87625c5.
Report an issue: GitHub.
Appendix: source
Thrown at integrations/aura/adapter.py:159
def aura_verdict(
did: str,
*,
base_url: str = DEFAULT_BASE_URL,
timeout: float = DEFAULT_TIMEOUT,
_fetch: Callable[[str, float], dict[str, Any]] = _http_get_json,
) -> AuraVerdict:
"""
Look up the trust verdict for a counterparty DID. Never raises on a
network/parse failure — returns an `unknown` verdict instead, leaving the
proceed/abort decision to the caller's policy (see before_settle).
v = aura_verdict("did:aura:z6Mk...")
print(v.verdict, v.reason, v.score)
`_fetch` is an injection seam for tests; production callers ignore it.
"""
if not did or not str(did).startswith("did:"):
raise ValueError(f"invalid DID: {did!r} (must start with 'did:')")
url = f"{base_url.rstrip('/')}/check?" + urllib.parse.urlencode({"did": did})
try:
body = _fetch(url, timeout)
except urllib.error.HTTPError as e:
return AuraVerdict.invalid_response(did, f"AURA returned HTTP {e.code}: {e.reason}")
except (urllib.error.URLError, TimeoutError, OSError) as e:
return AuraVerdict.unreachable(did, f"AURA unreachable: {e}")
except (json.JSONDecodeError, ValueError) as e:
return AuraVerdict.invalid_response(did, f"AURA returned non-JSON: {e}")
if not isinstance(body, dict):
return AuraVerdict.invalid_response(did, "AURA returned an unexpected shape")
return AuraVerdict.from_payload(did, body)
def before_settle(
did: str,View on GitHub (pinned to 8321021c54)