onetimesecret/onetimesecret · warning · ApplicationError
incoming.validation_form_errors
Error message
incoming.validation_form_errors
What it means
After the feature check, submit() runs validateForm(): memo is optional but must not exceed memoMaxLength (from config, default 50), secret must be non-empty after trim, and recipientId must be chosen. If any check fails, this aggregate human error is thrown while the per-field messages land in the errors ref (incoming.validation_secret_required, incoming.validation_recipient_required, incoming.validation_memo_too_long) for inline display.
Source
Thrown at src/shared/composables/useIncomingSecret.ts:151
* Creates API payload from form data
*/
const createPayload = (): IncomingSecretPayload => ({
memo: form.value.memo.trim() || '', // Empty string if no memo provided
secret: form.value.secret,
recipient: form.value.recipientId,
});
/**
* Handles form submission
*/
const submit = () =>
wrapSubmit(async () => {
if (!isFeatureEnabled.value) {
throw createError(t('incoming.validation_feature_disabled'), 'human');
}
if (!validateForm()) {
throw createError(t('incoming.validation_form_errors'), 'human');
}
const payload = createPayload();
const response = await incomingStore.createIncomingSecret(payload);
if (options?.onSuccess) {
await options.onSuccess(response);
} else if (response.success && response.record?.receipt?.key) {
// Default navigation to success view
await router.push({
name: 'IncomingSuccess',
params: { receiptKey: response.record.receipt.key },
});
}
return response;
});
View on GitHub (pinned to f81295e41b)
Solutions
- Read the errors ref after the failure - it names the exact offending field(s).
- Disable the submit button while !isFormValid (the composable already exposes it) so this throw never fires.
- Bind :maxlength="memoMaxLength" on the memo input to make the length failure impossible.
- Require the recipient select before enabling submit.
Example fix
// before <button @click="submit">Send</button> // after <button :disabled="!isFormValid || isSubmitting" @click="submit">Send</button> <input v-model="form.memo" :maxlength="memoMaxLength" />
Defensive patterns
Strategy: validation
Validate before calling
const canSubmit = computed(
() =>
!!form.value.secret.trim() &&
!!form.value.recipientId &&
form.value.memo.length <= memoMaxLength.value
)
if (!canSubmit.value) {
// highlight offending fields; do not call submit()
} Try / catch
submit() toasts the aggregate message via wrap; rely on the errors ref for per-field display and isFormValid to prevent the call entirely. No try/catch is needed.
Prevention
- Bind the submit button's disabled state to isFormValid
- Bind :maxlength on text inputs matched to server limits
- Validate on blur for early feedback
- Never prefill recipientId with an unvalidated value
When it happens
Trigger: Empty or whitespace-only secret; empty recipientId; memo longer than memo_max_length from /api/incoming/config (default 50 characters).
Common situations: User hits submit before selecting a recipient; long pasted memo because the input lacks a maxlength binding; programmatic submit without touching the form fields.
Related errors
- incoming.validation_feature_disabled
- Please check the form for errors
- Unable to create incoming secret. Please try again.
- Could not resolve domain for favicon removal
- Cannot burn this secret
AI-assisted analysis of onetimesecret/onetimesecret@f81295e41b (2026-08-23).
Data as JSON: /api/errors/1a6867e0ec4186ac.
Report an issue: GitHub.