lightninglabs / lightninglabs/taproot-assets
rpc: RPC handlers return codes.Unknown for predictable validation/lookup errors
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 525
- Forks
- 150
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 31
Description
Problem
Most tapd RPC handlers return plain fmt.Errorf / wrapped errors rather than status.Error(codes.X, ...). gRPC then surfaces these as codes.Unknown, leaving clients with no programmatic way to distinguish bad input from a missing resource from an internal failure — the error string is the only signal.
Caught while wiring typed errors through tap-sdk's REST transport (lightninglabs/tap-sdk#80). REST and gRPC now agree on the code, but that agreement is trivially Unknown == Unknown for every case we tried:
| RPC | Input | Actual | Expected |
|---|---|---|---|
DecodeAddr |
"not-a-tap-addr" |
Unknown: unable to decode addr: address: invalid bech32m string |
InvalidArgument |
DecodeProof |
[0x00, 0x01] |
Unknown: invalid raw proof, could not identify decoding format |
InvalidArgument |
ExportProof |
zero asset_id + zero script_key | Unknown: invalid script key: ... x coordinate 0x00..00 is not on the secp256k1 curve |
InvalidArgument (bad key) or NotFound (missing proof) |
Why it matters
SDK callers (Go, tap-sdk REST, any grpc-gateway client) want to branch on the error type — retry on Unavailable, surface InvalidArgument to the user, treat NotFound as a non-error, etc. Today they have to string-match, which is fragile and locale-sensitive.
Proposal
Audit the RPC surface and replace plain fmt.Errorf returns in handler paths with status.Errorf(codes.X, ...). Obvious mappings:
- Argument parsing/decoding (bech32, proof bytes, keys, hex/base64) →
codes.InvalidArgument - Explicit "not in DB" lookups →
codes.NotFound - Permission/macaroon →
codes.PermissionDenied - Shutdown / context canceled →
codes.Canceled/codes.Unavailable - Genuine internals (DB transaction failure, etc.) can keep the default
Unknown/Internal
A stricter pattern is to introduce a small helper that wraps known sentinel errors into status codes at the RPC boundary, keeping handler internals free of grpc imports.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by auditing the tapd RPC handler paths for the named DecodeAddr, DecodeProof, and ExportProof cases, reproducing their current gRPC errors. Map predictable parsing, lookup, permission, shutdown, and internal failures to the proposed status codes, then verify that clients receive distinguishable codes without changing genuine internal failures.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100