dotnet/aspnetcore · error · Error

Unknown action: ${action}

Error message

Unknown action: ${action}

What it means

Thrown by fetchAndSubmitCredential() when the action parameter is neither 'register' nor 'authenticate'. This is a defensive assertion guarding the two known submit flows; any other value indicates a logic error in how the form's submitter value is wired up.

Source

Thrown at src/Identity/samples/IdentitySample.PasskeyUI/wwwroot/app.js:87

            abortController?.abort();
            abortController = new AbortController();
            return await navigator.credentials.get({
                publicKey: options,
                mediation: useConditionalMediation ? 'conditional' : undefined,
                signal: abortController.signal,
            });
        }

        async function fetchAndSubmitCredential(action, useConditionalMediation = false) {
            try {
                const username = new FormData(form).get('username');
                let credential;
                if (action === 'register') {
                    credential = await fetchNewCredential(username);
                } else if (action === 'authenticate') {
                    credential = await fetchExistingCredential(username, useConditionalMediation);
                } else {
                    throw new Error('Unknown action: ' + action);
                }
                var credentialJson = JSON.stringify(credential);
                form.addEventListener('formdata', (e) => {
                    e.formData.append('action', action);
                    e.formData.append('credential', credentialJson);
                }, { once: true });
                form.submit();
            } catch (error) {
                // Ignore abort errors, they are expected when the user cancels the operation.
                if (error.name !== 'AbortError') {
                    statusMessage.textContent = 'Error: ' + error.message;
                    throw error;
                }
            }
        }

        form.addEventListener('submit', (e) => {
            if (e.submitter?.name == 'action') {

View on GitHub (pinned to 3600ca084e)

Solutions

  1. Check the submit button markup — every button with name='action' must have value 'register' or 'authenticate'.
  2. If adding a new action, extend the if/else-if chain in fetchAndSubmitCredential to handle it.
  3. Pass only known action literals when calling fetchAndSubmitCredential programmatically.

Example fix

// before
if (action === 'register') { /*...*/ }
else if (action === 'authenticate') { /*...*/ }
else { throw new Error('Unknown action: ' + action); }

// after (explicit allow-list)
const KNOWN_ACTIONS = new Set(['register', 'authenticate']);
if (!KNOWN_ACTIONS.has(action)) {
    throw new Error(`Unknown action: ${action}`);
}
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN_ACTIONS = new Set(['register', 'authenticate']);
function dispatch(action, useCond = false) {
  if (!KNOWN_ACTIONS.has(action)) {
    console.error(`Unknown action: ${action}`);
    return;
  }
  return fetchAndSubmitCredential(action, useCond);
}

Type guard

function isKnownAction(a) { return a === 'register' || a === 'authenticate'; }

Prevention

When it happens

Trigger: The submit handler reads e.submitter.value and passes it as action; if a button has name='action' but a value other than 'register'/'authenticate', or if fetchAndSubmitCredential is called programmatically with a typo, this branch fires. Also triggered during conditional mediation auto-auth (line 112) if the literal changes.

Common situations: Adding a third action button (e.g., 'delete credential') without extending the if/else chain; renaming submit button values in markup without updating JS; copy-paste error invoking fetchAndSubmitCredential with wrong argument.

Related errors


AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11). Data as JSON: /api/errors/e84102e76096156b. Report an issue: GitHub.