HTTP API

Diagnostic codes

The diagnostic codes a TERSL/DB caller can see on the wire, what each one means and what to do, the codes that appear only in the account's log, and the TERSL language diagnostics.

Overview#

A diagnostic code is a stable identifier at the start of a message, such as TERSE-STO-001 or TERSE028. This page lists the codes TERSL/DB writes on the wire and what to do about each, names the codes that appear only in the account's log, and lists the TERSL language diagnostics the engine reports.

Codes appear in three places:

  • in the Messages channel of a 200 answer from the Issue route, as error: declarations: TERSE-SEC-001: … or error: queries line 4: TERSE904: …;
  • in the first line of a refusal's body, as error: TERSE-STO-001: …;
  • in the streamed answer of /load, both as error: lines and in the reason of a refused summary.

Codes of the form TERSE-AREA-nnn are TERSL/DB's own. Codes of the form TERSE followed by three digits belong to the open TERSL specification. A refusal whose body has no code is described by its sentence; see Status codes.

Access#

Code Where Meaning What to do
TERSE-SEC-001 Messages of a 200: error: declarations: TERSE-SEC-001: <Right> at '<path>' is not permitted The key's grants do not allow that write at that path. The declarations were not applied. Ask the namespace's admin for the right, or write somewhere the key may write. See Keys, grants and visibility.
TERSE-SEC-001 The /load stream, before any batch: error: TERSE-SEC-001: Add at '<path>' is not permitted; nothing was processed The key can add or modify nothing under a root the file writes. Nothing was applied. As above.

A read the grants do not allow has no code: the answer leaves out what the key may not see.

Store#

Code Status Meaning What to do
TERSE-STO-001 503 The write lost every attempt to commit because of concurrent writes. Nothing was committed. Terse-Csn gives the head that stands. Retry after Retry-After.
TERSE-STO-002 422 A structural directive, such as [WAS], [REMOVED], [MOVED] or a placement, cannot be carried out as written. Nothing was committed. Rewrite the declaration as the message says.
TERSE-STO-003 500 The write failed at or after its commit point and may have committed at the CSN the message names. Resend with the same Terse-Idempotency-Key, or read the head and resend with Expected-Csn. See When the outcome is unknown.

Idempotency#

Code Status Meaning What to do
TERSE-IDM-001 422 The Terse-Idempotency-Key was already used for a different body, committed at the CSN the message names. Nothing was committed. Send a new key for a new write. On /load, a different batch size plans different batches, so it needs a new key too.

Content limits#

The content limits bound the size of one value in a write. Every size is counted in UTF-8 bytes, after line endings are normalised to LF. The limits are the deployment's and do not vary by plan. A TERSE-LIM refusal is a 413 with no Retry-After; the whole Issue is refused, nothing is applied and no query is answered. The body carries Terse-Diagnostics: errors=1; warnings=0 and no Terse-Csn.

Code What is measured
TERSE-LIM-001 A structural line: every line outside a """ text block, in either half of the Issue, including headers with their paths, directives, query lines, comments and one-line "…" values. Lines inside a block are not counted; the fences are.
TERSE-LIM-002 A name: each segment of a path is one name and is judged on its own.
TERSE-LIM-003 A header payload: a node's name and attribute list as the canonical form writes them, plus the line end. Heading marks, indentation and any path prefix are not counted, so the depth of a node does not decide whether it fits.
TERSE-LIM-004 A text value after the write applies, including an [APPEND], as content bytes. The same limit applies whether the value was written as "…" or as a """ block.

The message names the limit and its value, the measured size, the node's path or the half and line number, and quotes up to about 80 bytes of the content:

text
error: TERSE-LIM-001: queries line 2 is N bytes; MaxStructuralLineBytes is L; nothing was processed. It begins "? Places [WHERE…"

To fix a TERSE-LIM refusal, change the value: use a """ block instead of a long line, shorten the name, move attributes into content, or split the value across nodes. Splitting the request does not help, because an [APPEND] is judged on the value it produces. A value already stored over a limit stays readable; a write is refused only when it would make a value both over the limit and larger than it was.

Structural lines are judged first, before the grants. Names, header payloads and text values are judged after the grants, so a key that may not write a path receives TERSE-SEC-001 for it, not a size.

Load#

Code Where Meaning What to do
TERSE-LOAD-001 413 before the body, or in the stream The load body is over the deployment's load limit. Nothing was applied. Load a smaller file, or split it into several loads.
TERSE-LOAD-002 503 on other requests An exclusive load is running on the namespace. writes refuses Issues with declarations; all also refuses reads and history. Retry after Retry-After.
TERSE-LOAD-003 409 A load is already running on the namespace. Wait for it to finish.
TERSE-LOAD-004 503 The service is running as many loads as it allows. Retry after Retry-After.
TERSE-LOAD-005 503 The account already has a load running. Retry after Retry-After, or wait for the other load.
TERSE-LOAD-006 in the stream The service refused the file before applying anything. The stream lists every refusal with its file line. Fix the lines named and send the file again.

A file is refused with TERSE-LOAD-006 for invalid UTF-8, a """ block that is never closed, a structural line or a name over its content limit, a ? line, a wildcard header or a splice, or a stretch of the file with no legal place to cut it into batches. A refusal in the stream is followed by refused csn none wall N s reason <code> and committed through line 0.

Request#

Code Status Meaning What to do
TERSE-REQ-001 504 The request did not answer within the deployment's request time limit. If the body ends ; nothing was processed, the request was not processed. Otherwise the write may have been applied, and it is recorded when it lands. Find out whether it landed before resending; see When the outcome is unknown.

Codes in the account's log only#

Some refusals are recorded in the account's log with a code, while their body on the wire is a sentence without one. Search the log on the Logs page for these:

Code Log event Wire answer
TERSE-ADM-001, TERSE-ADM-002, TERSE-ADM-003 request.throttled 429 or 503: too many requests in flight for the namespace, the account or the deployment
TERSE-ADM-004 request.throttled 503: the deployment is at its memory limit
TERSE-GOV-001, TERSE-GOV-002, TERSE-GOV-006, TERSE-GOV-007, TERSE-GOV-008 request.throttled 429: a rate window of the plan refused the request
TERSE-GOV-003 request.too_large 413: the body is over the plan's request-size limit
TERSE-GOV-005 request.storage_full 507: the namespace is at the plan's namespace-size limit
TERSE-REC-001 record.level.refused a write refused because of the namespace's record level
TERSE-ACCT-001 request.suspended 403: the account is suspended

Language diagnostics#

The TERSL engine reports problems in the text it reads with the specification's codes, TERSE001 to TERSE046 and TERSE901 to TERSE931, and the non-numeric TERSE_QUERY_ERR. They appear in the Messages channel with the channel and line they belong to, keeping their code and text: an error as error:, anything else as warn:. Line numbers in a /load stream are the file's.

An error drops only the unit it names: a line, or a header and the subtree beneath it, while the rest of the request is applied. An error: line in a 200 therefore does not mean nothing was committed; Terse-Csn says whether the head moved. The full text of each code is in section 13, "Diagnostic Codes", of the specification in the open-source repository, terse-lang/terse (terse-spec/TERSE_Specification.md). The table lists the codes the TERSL/DB engine emits.

Code Severity Raised by What is ignored
TERSE001 error an unbalanced or stray (, ), [ or ], or a directive tail missing its ] the line, and a header's subtree
TERSE002 error an unclosed string the line
TERSE005 warning a + prefix in an attribute list nothing
TERSE009 error an empty segment, ;;, in a list the empty segment
TERSE013 error a bracketed flag with no name the segment
TERSE014 warning the same identifier key twice in one list nothing; the last wins
TERSE021 error a name, segment or key that reduces to an empty handle the header and subtree, the object line, or the key segment
TERSE022 error a ?Name segment in a query path the query line
TERSE025 error a malformed [WHEN] the expression selects nothing
TERSE026 warning an unknown escape inside "…" nothing; both characters are kept
TERSE027 error an unclosed """ block, or text after """ on the opening line the block
TERSE028 error a forbidden character in a name, two @ references on one line, or attributes after a reference the header and subtree, the object line, the key segment, or the query line
TERSE030 error a " where no value starts, or text after a closing quote the character is kept; the trailing text is discarded
TERSE031 warning a name that collides with a node already present nothing; the existing node and its display name are kept
TERSE032 warning a placement anchor that is not an earlier sibling of the same kind the node is not moved
TERSE034 error more than one placement directive on a line the last one wins
TERSE036 error the retired parenthesised form WAS(…), AS(…), WHERE(…) or WHEN(…), or a capitalised directive after a query path without brackets the header and subtree, the object line, or the query line
TERSE037 error # in a query path segment the query line
TERSE039 error an empty directive tail, [] the tail
TERSE040 error an unknown directive keyword that segment
TERSE045 warning a second text value on one node that is not an append the first value
TERSE046 error TEXT used where it is reserved the header and subtree, the line, or the expression
TERSE901 warning a [WAS Old] that matches nothing, where the new name does not exist either the declaration
TERSE902 error [WAS] on a query line the query line
TERSE903 error a byte-order mark at the start of a line other than the first nothing; the line is read as its bytes say
TERSE904 error a * in the middle of a query path on a read the expression
TERSE906 error a whole-segment * in a header where a wildcard is not allowed the header and subtree
TERSE907 warning a wildcard header, splice, (*) or [FROM] that matched nothing nothing was done
TERSE908 warning a [WHERE] on a wildcard header or shape line that does not compile it matches nothing
TERSE910 warning an [AS] that matched more than one node the first match is used
TERSE911 error an illegal wildcard header: two wildcards, a query directive other than WHERE, or a mutation directive the header and its block
TERSE912 error a directive a ? command cannot carry out the line
TERSE913 error [AS] on a declaration the header and subtree, or the line
TERSE915 error the root header with a directive other than [REMOVED] the line and subtree
TERSE916 error a ## or deeper header with no name the line and subtree
TERSE917 error [CONTAINERS] or [OBJECTS] on a command without a wildcard the line
TERSE918 error [CONTAINERS] or [OBJECTS] on a declaration header the header and its block
TERSE919 error [OBJECTS] together with [CONTAINERS] the line
TERSE920 error an anchored placement on a wildcard command without a kind selector the line
TERSE921 error a literal * outside a string the line, and a header's subtree
TERSE922 error a directive tail on an object splice the line
TERSE923 error a second […] group on a line the line
TERSE924 error [CONTAINERS n] or [OBJECTS n] the line
TERSE925 error a line in a shape block that is not a shape line, two wildcards in a shaping path, or a line under a * the line and its body, or the block
TERSE926 error a malformed [FROM] path the line and its body
TERSE927 error a classifier line with no anchor it can reach the line
TERSE928 warning a ? with a placement or sizing directive that owns a body; it places rather than shapes nothing; the body stays ordinary declarations
TERSE929 warning a shape body that reads the children of an object binding those lines
TERSE931 warning a [WHERE] on a read that does not compile the expression selects nothing
TERSE_QUERY_ERR error ?Foo with no space, a malformed [DEPTH], [REMOVED] with a copy directive, or [NEW] with [FILL] the query line or the expression

The language itself is described in Reading with queries and Writing with declarations.