Stirling-Tools/Stirling-PDF · error · Error
Failed to submit signature
Error message
Failed to submit signature
What it means
Thrown by submitSignature() in useParticipantSession after workflowService.submitSignature (or the subsequent loadSession reload) rejects. The hook first tries to extract a usable message: axios errors use response.data.message, other Errors use err.message, and only if neither exists does it fall back to 'Failed to submit signature'. The thrown Error carries the original as {cause} and the same string is set into the error state for UI.
Source
Thrown at frontend/editor/src/proprietary/hooks/workflow/useParticipantSession.ts:72
const submitSignature = useCallback(
async (request: SignatureSubmissionRequest) => {
setLoading(true);
setError(null);
try {
const updatedParticipant =
await workflowService.submitSignature(request);
setParticipant(updatedParticipant);
// Reload session to get updated status
if (request.participantToken) {
await loadSession(request.participantToken);
}
} catch (err: unknown) {
const errorMsg = isAxiosError(err)
? err.response?.data?.message || err.message
: (err instanceof Error ? err.message : undefined) ||
"Failed to submit signature";
setError(errorMsg);
throw new Error(errorMsg, { cause: err });
} finally {
setLoading(false);
}
},
[loadSession],
);
const decline = useCallback(
async (token: string, reason?: string) => {
setLoading(true);
setError(null);
try {
const updatedParticipant = await workflowService.declineParticipation(
token,
reason,
);
setParticipant(updatedParticipant);
// Reload sessionView on GitHub (pinned to 9ef20dcab8)
Solutions
- Check the axios response status/message shown in error state — it usually carries the real backend reason.
- Ensure SignatureSubmissionRequest has a valid participantToken and all required signature fields before submitting.
- Handle the thrown error at the call site (it re-throws after setting state) and surface the backend message to the user.
- If the token expired, re-issue/re-fetch the participant link rather than retrying the same request.
Example fix
// before
try { await submitSignature(req); } catch { /* swallow */ }
// after
try {
await submitSignature(req);
} catch (e) {
showToast(e instanceof Error ? e.message : 'Signature failed');
if (tokenExpired(e)) refreshParticipantLink();
} Defensive patterns
Strategy: try-catch
Validate before calling
const req = request;
if (!req.participantToken) {
setError('Participant token is required');
return;
}
// ensure signature fields are populated before calling submitSignature Type guard
export function isCompleteSignatureRequest(r: SignatureSubmissionRequest): boolean {
return Boolean(r.participantToken);
} Try / catch
try {
await submitSignature(request);
} catch (e) {
const msg = e instanceof Error ? e.message : 'Signature failed';
showToast(msg);
if (/token|expired|unauthorized/i.test(msg)) refreshParticipantLink();
} Prevention
- Disable the submit button while loading and after first click to prevent double-submit races.
- Validate the participant token hasn't expired before rendering the sign UI.
- Always surface error state (already set by the hook) to the user rather than swallowing the re-thrown error.
When it happens
Trigger: Backend rejects the signature (invalid signature image, missing required fields, participant token expired, session already completed/declined); network failure during the POST; participantToken missing so the session reload is skipped but the submit itself failed; concurrent double-submit where the second call hits a now-invalid state.
Common situations: Participant let their email token link expire; the workflow session was cancelled by an admin mid-sign; backend validation rejects an empty signature pad; flaky network on mobile; the request.participantToken is undefined so signature submits but state desyncs.
Related errors
- Failed to decline
- Supabase is not configured
- Unknown policy category: ${id}
- Supabase is not configured. Please use static plans instead.
- Failed to fetch plans: ${error.message}
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/4e32245013fd1585.
Report an issue: GitHub.