Repository navigation
Return 400 when Neko rejects a display configuration - #501
Merged
Merged
Conversation
hiroTamada
approved these changes
Nov 4, 2026
hiroTamada
left a comment
Contributor
There was a problem hiding this comment.
reviewed — the change is tight and well tested. nothing blocking, just one fyi and some nits:
Questions
server/cmd/api/api/chromium_configure.go:296— on the stop/start path, the display 400 comes back after policies/extensions were already applied (same as the extensions 400 at :277). fine with that, just flagging that a 400 here doesn't mean nothing was applied.
Nits
server/cmd/api/api/chromium_configure.go:847— nit: the extensions 400 is prefixed with the step name (extensions: ...); considerdisplay: ...so they match.server/lib/nekoclient/client.go:13-16— nit: "retrying cannot succeed" holds in practice because neko holds a mutex, but 422 also covers RRSetConfigInvalidTime/Failed from XRRSetScreenConfigAndRate. maybe soften to "is not expected to succeed".server/lib/nekoclient/client_test.go:20-23— consider adding a 401 → retry → 422 case. the login handler in both fakes never runs today because the first request goes out with no token.server/cmd/api/api/display_test.go:631— nit: the fake Neko body is hardcoded to"code":422, even for the 500 subtests.server/cmd/api/api/display_test.go:669-674,686-690— nit: the 500 subtests could assert the message still includes Neko's status, which would catch a mapping that's too broad.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When Neko can't set a screen configuration, it returns 422 (
cannot set screen size). kernel-images passes that back as a 500 from bothPATCH /displayand/configure, so callers can't tell "this size isn't supported" apart from a server fault. The control plane only turns a 4xx from the VM into a client error; a 500 gets treated as a broken instance, retried on other instances, and then reported as a generic 500.Change
nekoclient.ScreenConfigurationChangewraps a 422 in the newErrScreenConfigurationRejected. Other non-2xx statuses are unchanged.PATCH /display(Xorg path) and the/configuredisplay step applied while Chromium is stopped return 400the display cannot be set to WxH at R Hzfor that error. The live/configurepath goes throughpatchDisplayLocked, so it gets the 400 as well. Every other failure is still a 500.This doesn't make more sizes work. The root cause, generated modes that X lists at one Hz below the requested rate, is fixed in kernel/neko#31. With that fix in, the remaining 422s are sizes the X server can't set at all, for example anything below 64x64.
Testing
TestScreenConfigurationChangeStatuscovers 200, 422 and 500 from a fake Neko.TestPatchDisplayNekoRejectionandTestChromiumDisplayApplyWhileStoppedNekoRejectiondrive the real handlers against a fake Neko and a fakexrandr: a 422 becomes a 400 and a 500 stays a 500.go test -racepasses for every non-e2e package exceptTestUpstreamManagerDetectsChromiumAndRestart(devtoolsproxy, untouched). It failed once on a temp-dir cleanup race and passed when rerun.PATCH /browsers/{id}to 63x400 returned 400viewport_configuration_failed/the display cannot be set to 63x400 at 60 Hzin 0.2s. Before, it returned 500failed to update session.Notes
display.go, in separate hunks. This branch merges cleanly with Restart Chromium when a headful display change only changes the refresh rate #497 as it stands.chromiumDisplayApplyWhileStoppedcalls the fork-onlyapplyXorgDisplayResolutionthere. The resolution is to keep the fork'sbadReqhandling and add theErrScreenConfigurationRejectedcheck after it. I built and ran exactly that for the production test.ghcr.io/kernel/neko/basein both Dockerfiles once Generate screen modes at the exact requested size and refresh rate neko#31 is tagged.Note
Low Risk
Behavior change is limited to HTTP status mapping for an existing Neko 422 path; no auth or data-handling changes.
Overview
When Neko’s screen API returns 422 (X refused the requested mode), callers previously saw 500, which made unsupported viewports look like a broken VM. This PR classifies that case as a client error.
nekoclient.ScreenConfigurationChangenow wraps HTTP 422 inErrScreenConfigurationRejected. Other non-2xx responses are unchanged.PATCH /displayand the Chromium/configuredisplay step (including live configure viapatchDisplayLocked) map that sentinel to 400 withthe display cannot be set to WxH at R HzviaunsupportedDisplayMessage. All other resize failures still return 500.Tests cover the Neko client status handling and both API paths (422 → 400, 500 → 500).
Reviewed by Cursor Bugbot for commit 1200e1f. Bugbot is set up for automated code reviews on this repo. Configure here.