ruvnet/ruflo · error · TypeError
Unknown federation claim: ${claim}
Error message
Unknown federation claim: ${claim} What it means
Every entry in config.grantedClaims must be a member of the package's FEDERATION_CLAIMS vocabulary; unknown strings throw a TypeError during checker construction. The strictness is deliberate: under 'enforce' mode a typo'd claim would silently never match and permanently deny operations, so misconfiguration is surfaced immediately.
Source
Thrown at v3/@claude-flow/plugin-agent-federation/src/application/claim-checker.ts:51
* - observe: calculate and report missing grants without blocking;
* - enforce: default deny unless the exact claim is configured.
*
* ADR-324 policy adapters can supply the `grantedClaims` set after evaluating
* the request; ownership-changing federation messages remain disabled in the
* default message policy until the full ingress PEP is composed.
*/
export function createFederationClaimChecker(
config: FederationClaimCheckerConfig = {},
): FederationClaimChecker {
const mode = config.mode ?? 'legacy';
if (mode !== 'legacy' && mode !== 'observe' && mode !== 'enforce') {
throw new TypeError(`Unsupported federation authorization mode: ${String(mode)}`);
}
const grantedClaims = new Set<FederationClaimType>();
for (const claim of config.grantedClaims ?? []) {
if (!FEDERATION_CLAIMS.has(claim as FederationClaimType)) {
throw new TypeError(`Unknown federation claim: ${claim}`);
}
grantedClaims.add(claim as FederationClaimType);
}
return {
mode,
grantedClaims,
checkClaim: (claim) => {
const granted = grantedClaims.has(claim);
if (mode === 'observe') config.onObservation?.(claim, granted);
return mode !== 'enforce' || granted;
},
};
}
View on GitHub (pinned to fa13ee4ad6)
Solutions
- Fix the claim string to the exact federation claim type exported by the package
- Source grant lists from the package's exported claim vocabulary rather than hand-typed literals
- Align adapter and package versions when the claim set changed between releases
- Log the exported claim set once at startup so drift is visible in ops output
Example fix
// before
createFederationClaimChecker({ mode: 'enforce', grantedClaims: ['message:send'] }); // not in vocabulary
// after
// use only claims drawn from the package's federation claim vocabulary
createFederationClaimChecker({ mode: 'enforce', grantedClaims: validClaims }); Defensive patterns
Strategy: type-guard
Validate before calling
// derive grant lists from the exported vocabulary, never hand-type them
import { FEDERATION_CLAIMS } from '@claude-flow/plugin-agent-federation'; // if exported
const grantedClaims = [...FEDERATION_CLAIMS].filter(c => policy.allows(c));
createFederationClaimChecker({ mode: 'enforce', grantedClaims }); Type guard
function isKnownFederationClaim(c: unknown): c is FederationClaimType {
return (
typeof c === 'string' &&
FEDERATION_CLAIMS.has(c as FederationClaimType)
);
} Prevention
- Source claims from the package's exported vocabulary
- Avoid free-form claim strings in adapters — map to known claim types
- Add a startup assertion that every configured claim is known
- Re-check claim lists after package upgrades
When it happens
Trigger: Typos in claim strings ('mesage:send' for 'message:send'); claim names invented by the integrator instead of taken from the federation vocabulary; claims valid in a newer/older package version passed across a version skew; an ADR-324 adapter emitting arbitrary strings as claims.
Common situations: Grant lists hand-copied from docs of a different version; adapters mapping internal permissions to free-form strings; renamed claims after a package upgrade.
Related errors
- Issue ${input.issueId} is not claimed by ${input.claimantId}
- UNAUTHORIZED
- Only the original claimant can contest the steal
- Unsupported federation authorization mode: ${String(mode)}
- unknown game "${key}". Known: ${Object.keys(GAMES).join(', '
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/d5486c661b45e7e4.
Report an issue: GitHub.