xpipe-io/xpipe · error · BeaconClientException

Unknown askpass request

Error message

Unknown askpass request

What it means

AskpassExchange resolves an interactive password prompt to a registered secret-query progress previously set up for that request. When neither the request id alone nor request+secretId matches a known progress entry in SecretManager, the handler throws BeaconClientException('Unknown askpass request').

Source

Thrown at app/src/main/java/io/xpipe/app/beacon/api/AskpassExchange.java:89

            return Response.builder().value(InPlaceSecretValue.of("")).build();
        }

        var prompt = msg.getPrompt();
        // sudo-rs uses a different prefix which we don't really need
        prompt = prompt.replace("[sudo: authenticate]", "[sudo]");

        if (msg.getRequest() == null) {
            var r = AskpassAlert.queryRaw(prompt, null, false);
            return Response.builder()
                    .value(r.getState() == SecretQueryState.NORMAL ? r.getSecret() : InPlaceSecretValue.of(""))
                    .build();
        }

        var found = msg.getSecretId() != null
                ? SecretManager.getProgress(msg.getRequest(), msg.getSecretId())
                : SecretManager.getProgress(msg.getRequest());
        if (found.isEmpty()) {
            throw new BeaconClientException("Unknown askpass request");
        }

        var p = found.get();
        var secret = p.process(prompt);
        if (p.getState() != SecretQueryState.NORMAL) {
            var ex = new BeaconClientException(SecretQueryState.toErrorMessage(p.getState()));
            ErrorEventFactory.preconfigure(ErrorEventFactory.fromThrowable(ex).ignore());
            throw ex;
        }
        focusTerminalIfNeeded(msg.getPid());
        return Response.builder().value(secret.inPlace()).build();
    }

    @Override
    public boolean requiresEnabledApi() {
        return false;
    }

View on GitHub (pinned to d85ca821ba)

Solutions

  1. Re-initiate the original request that required the secret so a fresh askpass progress is registered, then answer its prompts.
  2. Verify the request id and secretId in the askpass message match the currently active query (check for typos or reused ids).
  3. Ensure prompts are answered promptly before the query times out or completes.
  4. After a daemon restart, restart the whole connection flow instead of replaying old askpass messages.

Example fix

// before
answerPrompt(oldRequestId, secretId, password); // progress already gone
// after
var req = client.startConnection(connId); // registers a fresh query
answerPrompt(req.getRequestId(), req.getSecretId(), password);
Defensive patterns

Strategy: try-catch

Try / catch

try {
    answerAskpass(requestId, secretId, password);
} catch (BeaconClientException e) {
    if (e.getMessage().contains("Unknown askpass request")) {
        // query expired/completed: restart the connection flow to register a new query
        restartConnectionFlow();
    }
}

Prevention

When it happens

Trigger: An askpass prompt arrives for a request whose progress entry already completed or was cleaned up; the secretId doesn't correspond to a progress registered for that request id; the daemon restarted between query registration and prompt; sending prompts for requests never initiated through the API.

Common situations: Scripts replaying captured askpass messages out of order; timeouts cancelling the query before the prompt is answered; multiple concurrent queries causing id mix-ups; stale clients after a daemon restart.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of xpipe-io/xpipe@d85ca821ba (2026-09-06). Data as JSON: /api/errors/428773a98f8b0a84. Report an issue: GitHub.