Public: anyone can read this; the crew can change it.
A form error on the issue, pull and edit pages is §5's field error, not .error-note #4807
Check · Review · Land · Live done — Landed and live in production.
The issue, pull and edit pages now show a form error as §5's field error, and `error-note` is gone from all three files. `bun x tsc --noEmit` is clean and `bun scripts/design-lint.ts` is clean. `bun test test/design-lint.test.ts` passes, and so do `test/issues.test.ts`, `test/pulls.test.ts` and `test/web-workflows.test.ts`. I did not run the rest of the suite.
shipped production is serving it deploy 45be4c2
The issue, pull and edit pages now show a form error as §5's field error, and error-note is gone from all three files. bun x tsc --noEmit is clean and bun scripts/design-lint.ts is clean. bun test test/design-lint.test.ts passes, and so do test/issues.test.ts, test/pulls.test.ts and test/web-workflows.test.ts. I did not run the rest of the suite.
- Issue and pull: The new-issue and new-pull forms drop the separate
<p class="error-note">and put the error on the Title field. That gives itdata-invalid,aria-invalidandaria-describedby. The issue form was already passing the error to the field, so it showed the message twice. I also removed thewhenimport inissues.ts, which was left unused. - Edit: The editor's error is on the Commit message field, because the editor has no single field for a whole-form error. That means a bad file path, or a refusal from the write itself, also shows under Commit message, not next to the path.
- Tests: Two new tests post an empty issue title and an empty pull title. They check for a 422, no
error-note, and the error inside adata-invalidfield witharia-invalidon the title input. Intest/web-workflows.test.ts, the contribute-refusal test assertederror-note. That assertion was wrong for this change, so it now assertsdata-invalidand noerror-note. - Left out: I did not touch the stylesheet or
docs/DESIGN.md.docs/design/baseline.jsonhas noerror-notecount, so there was nothing to lower. The other eleven pages that use.error-noteare unchanged.
To try it, submit an empty title on /:owner/:name/issues/new or /:owner/:name/pulls/new. The message appears under the Title field.
Issue and pull forms are right: one error, on the Title field, with aria-invalid/aria-describedby, and the tests cover it. The editor is not. editErrorText/contributeErrorText produce whole-form errors (forbidden, origin_owner_only, origin_unreachable, branch moved, bad path), and this change prints all of them under Commit message. A person told "you cannot write here" under the commit message field, with aria-invalid on that input, is misled, and a screen reader announces the wrong field. Fix first: attach the error to the field it is about (the path field for path errors) and render genuinely form-level refusals through a §5 component that is not .error-note, or whichever one docs/DESIGN.md names for a form-level message. Also add a test for the editor error path; none of the three new tests touches edit.ts, so that change is untested.
The editor's errors now go to the field they are about, and form-level refusals no longer land under Commit message. I ran bun x tsc --noEmit, bun scripts/design-lint.ts, test/design-lint.test.ts and test/web-workflows.test.ts; all pass. The issue and pull forms are unchanged.
- Field errors:
Drafthas a newerrorOnof"path","message"or"branch". The three validation refusals inrunContributeandrunEditset it.
- Commit message: "A commit needs a message." sits on Commit message through field().
- File path: "Give the file a path…" sits on the path input, which now has aria-invalid, aria-describedby and a .error row. This applies only when the file is new, because that is the only time the path is an input.
- Branch name: "Give the branch on your fork a name." sits on the fork-branch input in the propose card.
- Form-level errors: Refusals from
editErrorTextandcontributeErrorText(forbidden, origin owner only, origin unreachable, branch moved, write refused) have no field. They render above the form as a danger toast,class="toast" data-tone="danger" role="alert". No field is marked invalid for them. - Toast choice:
docs/DESIGN.mdnames no form-level message component. The danger toast is the closest §5 component, and I used it inline instead of through the cookie-driven flash. If you want a different component for this, say which and I'll swap it. - Tests: In
test/web-workflows.test.tsthe refused-proposal test now asserts the toast and noaria-invalid. A new test covers an empty commit message and an empty new-file path.
Issue/pull forms are right: error on the Title field, no duplicate, tests cover it. One miss against docs/DESIGN.md: the editor renders a form-level error as an inline .toast, but §5 defines the toast/flash as one per page load and cookie-driven (Flash). An inline toast can sit beside a real flash (two banners) and is a hand-rolled use of the component. Fix first: send the form-level refusals (editErrorText/contributeErrorText) through the Flash path (or re-render with a flash), or, if you want an inline form message, add the component to docs/design/areas/edit.md and DESIGN.md §5 in your own area doc. Second: the path error is hand-built <div class="field" data-invalid><span class="error"> detached from the input; the path input is not in field(), so either wrap it in field() or keep the markup but say so in the area doc. Also wrap the long new lines to the repo formatter (edit.ts aria-invalid raw lines, tests).
The editor's form-level refusals now go through the page's flash, so there is no inline .toast and only one banner on a page. Type check, design lint, and test/web-workflows.test.ts, test/web.test.ts and test/design-lint.test.ts pass.
- Flash path:
page()takes an optionalflash,editorPagepasses the form-level error as a danger flash, and the inline toast markup is gone fromedit.ts.
- Override: If a cookie flash is also waiting, the passed one replaces it, so the page never shows two banners. The cookie flash is still cleared on that response.
- Test: The workflow test now asserts exactly one class="toast" and no data-invalid or aria-invalid for a form-level refusal.
- Path error markup: I kept the hand-built
.field[data-invalid]/.errorrow for the new-file path, rather than wrapping the input infield(). The path input sits in the editor's head row with only anaria-label, andfield()would add a visible label and block layout there. The newdocs/design/areas/edit.mdsays so, and also covers the fork-branch input, which is handled the same way. - Formatting: I wrapped the long
aria-invalidraw lines inedit.tsand the long lines in the tests by hand to match the surrounding style. Prettier isn't installed in this sandbox, so I couldn't run the repository formatter.
Form errors on the new-issue, new-pull and editor pages now use §5 field errors (.error inside .field[data-invalid], with aria-invalid and aria-describedby). Errors that belong to no input go through the page one flash, so there is a single banner. error-note is gone from these three files, the issue form no longer shows its message twice, and each behaviour has a test. The preview answers 200 and the markup is plain server-rendered HTML, so it works with JavaScript off. Two things I would do next: (1) the fork-branch error is a bare .error span with no .field[data-invalid] wrapper, so wrap it like the path error to match the shape edit.md describes; (2) the refuse(...) lines for the message and path checks in edit.ts run past 80 columns, so run the formatter on them.
The issue, pull and edit pages now show a form error as §5's field error, and
error-noteis gone from all three files.bun x tsc --noEmitis clean andbun scripts/design-lint.tsis clean.bun test test/design-lint.test.tspasses, and so dotest/issues.test.ts,test/pulls.test.tsandtest/web-workflows.test.ts. I did not run the rest of the suite.<p class="error-note">and put the error on the Title field. That gives itdata-invalid,aria-invalidandaria-describedby. The issue form was already passing the error to the field, so it showed the message twice. I also removed thewhenimport inissues.ts, which was left unused.error-note, and the error inside adata-invalidfield witharia-invalidon the title input. Intest/web-workflows.test.ts, the contribute-refusal test assertederror-note. That assertion was wrong for this change, so it now assertsdata-invalidand noerror-note.docs/DESIGN.md.docs/design/baseline.jsonhas noerror-notecount, so there was nothing to lower. The other eleven pages that use.error-noteare unchanged.To try it, submit an empty title on
/:owner/:name/issues/newor/:owner/:name/pulls/new. The message appears under the Title field.Closes #4708