Repository navigation
fix: mask market and catalog errors to a closed set, and keep originals out of the gateway's - #28
Merged
Merged
Conversation
|
Hebilicious
added this pull request to stack #37
October 13, 2026 20:10
Hebilicious
force-pushed
the
audit/error-masking
branch
from
October 13, 2026 20:12
25a141a to
706bd8d
Compare
Hebilicious
force-pushed
the
audit/error-masking
branch
from
October 14, 2026 06:04
706bd8d to
2fd9edc
Compare
Hebilicious
removed this pull request from stack #37
October 14, 2026 06:05
Hebilicious
added this pull request to stack #42
October 14, 2026 06:05
Hebilicious
force-pushed
the
audit/error-masking
branch
from
October 14, 2026 06:10
2fd9edc to
876c57a
Compare
Hebilicious
force-pushed
the
audit/error-masking
branch
from
October 14, 2026 07:09
876c57a to
97ec0a6
Compare
…ls out of the gateway's The market and catalog Yogas ran with maskedErrors: false, and the gateway passes a subgraph's errors through as the subgraph wrote them, so internal text such as "Huffman file header is invalid" or "Pearl Abyss positional row has an unknown shape" reached callers. - The market subgraph lets out only its own closed set: BAD_USER_INPUT, QUERY_BUDGET_EXCEEDED and UPSTREAM_UNAVAILABLE, each with a fixed message. A failed Pearl Abyss read is UPSTREAM_UNAVAILABLE without its reason. Client argument errors (item IDs, enhancement levels) keep their message as BAD_USER_INPUT. Anything else is INTERNAL_SERVER_ERROR with one fixed message. - The catalog subgraph does the same: an item ID that is not a positive whole number in item(id:), items(ids:) and entity references is BAD_USER_INPUT, and anything else is INTERNAL_SERVER_ERROR. createCatalogSubgraph takes an optional itemNameSearch, which the scenario uses to make a search fail. - The gateway masks its own errors with isDev: false, so the original error and its stack stay out even where NODE_ENV says development. market-error-semantics (market-client-input-errors, market-internal-errors-masked, gateway-errors-masked-in-development) and catalog-error-semantics prove it end to end. docs/api.md lists the codes. The catalog identity is regenerated, since the subgraph's code is part of it. Refs #12
Hebilicious
force-pushed
the
audit/error-masking
branch
from
October 14, 2026 08:50
97ec0a6 to
be0f9fa
Compare
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.
Closes #12
What changed
Market subgraph (
packages/market-subgraph/src/index.ts):maskedErrorsnow uses a mask that lets out only errors made bymarketError:BAD_USER_INPUT;QUERY_BUDGET_EXCEEDED;UPSTREAM_UNAVAILABLE, with the fixed message "The Central Market could not be read.". Every failed Pearl Abyss read gets this code in this layer.Item ID and enhancement-level argument errors keep their messages as
BAD_USER_INPUT. Anything else becomesINTERNAL_SERVER_ERRORwith one fixed message.Catalog subgraph: the same kind of closed set. An item ID that is not a positive whole number in
item(id:),items(ids:)or an entity reference isBAD_USER_INPUT; anything else isINTERNAL_SERVER_ERROR.createCatalogSubgraphtakes an optionalitemNameSearch, which a test uses to make a search fail.Gateway:
maskedErrors: { isDev: false }, so the original error and its stack stay out even whenNODE_ENV=development.Tests: new
market-error-semanticsfeature, with the scenarios this layer needs, and newcatalog-error-semanticsfeature. Both are added to the test tsconfigs.docs/api.mdlists the codes.The catalog identity is regenerated.
In this layer, a throttled Pearl Abyss read is masked to
UPSTREAM_UNAVAILABLE.audit/throttle-and-budget-errorsgives it its ownRATE_LIMITEDcode.How it was reproduced
I ran this layer's two features against the parent layer (
audit/repo-hygiene):market-client-input-errors{"message":"Item ID must be a positive safe integer", …, "code":"DOWNSTREAM_SERVICE_ERROR"}, notBAD_USER_INPUTmarket-internal-errors-masked["DOWNSTREAM_SERVICE_ERROR", …, "Pearl Abyss response is not ASCII text"]. That is the leak: internal transport text reaches the clientgateway-errors-masked-in-developmentThe input was expected to not match … /internal plugin detail 7f3a/u. The plugin's internal message reaches the clientcatalog-client-input-errors{"message":"Item ID must be a positive safe integer", …}has noBAD_USER_INPUTcodecatalog-internal-errors-maskedactual: undefined)Not reproduced
catalog-internal-errors-maskedfails on the parent only because the parent has noitemNameSearchseam, so the failing search cannot be injected. That the catalog's internal text leaked was confirmed by reading the code (maskedErrors: false), not by a failing assertion on its text.catalog(category: {main: 0})returning "Unsupported Pearl Abyss Central Market category") was not repeated, because there is no live traffic.audit/summary-and-catalog-limitscovers that message locally.Refs #21 (security audit tracking issue). Part of stack #42; review bottom-up, each layer shows only its own diff.