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

  1. Ensure the DID is loaded/provisioned before calling — check the agent identity config or keychain entry exists
  2. Prefix raw keys with the scheme, e.g. 'z6Mk...' -> 'did:aura:z6Mk...'
  3. Trim whitespace/quotes around the configured DID value
  4. 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

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


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)