Summary
Calling comment.distinguish(true) on a comment that has ever been edited rejects with a gRPC
status-2 error from the platform, even though the distinguish/sticky is actually applied on Reddit.
The root cause is a protobuf contract mismatch: Reddit's API returns edited as false or a float
epoch timestamp, but Devvit's RedditObject.edited is declared google.protobuf.BoolValue, so the
gateway fails to marshal the (successful) response.
Environment
- App:
confessor-mod, installed on r/confession
- SDK:
@devvit/web 0.13.6 (@devvit/protos 0.13.6; flaw still present in latest @devvit/protos 0.13.10)
- Observed in production: 2026-07-28 ~07:07 UTC
Observed error
[remove] sticky distinguish failed: Error: 2 UNKNOWN: grpc invocation failed with status 2; proto: (line 1:182): invalid value for bool field value: 1785222440.0
at callErrorFromStatus (/srv/index.cjs:5452:21)
at Object.onReceiveStatus (/srv/index.cjs:6133:70)
...
at GenericPluginClient.Distinguish (/srv/index.cjs:137177:93)
at tM.distinguish (main.js:6:10378)
at tM.distinguish (main.js:6:8096)
code: 2,
details: 'grpc invocation failed with status 2; proto: (line 1:182): invalid value for bool field value: 1785222440.0'
Note 1785222440.0 = 2026-07-28T07:07:20Z — the exact time the app had just edited the comment
before distinguishing it. It is the comment's edited timestamp, not anything the app passed: the
app called comment.distinguish(true) with a literal boolean, and @devvit/reddit's
Comment.distinguish sends only { id, how: 'yes', sticky: true }, which matches
DistinguishRequest (moderation_msg.d.ts:65-72). The failure is in the response path.
Root cause
Moderation.Distinguish returns JsonRedditObjects (moderation_svc.d.ts:34), whose
things[].data is RedditObject (common/common_msg.d.ts). In that message:
approvedAtUtc, bannedAtUtc, created, createdUtc are correctly typed as numbers, but
edited is declared as a bool wrapper: edited?: boolean | undefined (common_msg.d.ts:207-208),
encoded as google.protobuf.BoolValue (common_msg.js:841-842:
BoolValue.encode({ value: message.edited }, ...)).
Reddit's API returns edited: false for never-edited things and edited: <float epoch> for edited
things. When the gateway converts Reddit's JSON response for a distinguish call into the proto, an
edited comment's timestamp cannot unmarshal into BoolValue — hence the Go protojson error naming
the wrapper's inner field: invalid value for bool field value: 1785222440.0.
Consistent with this, the error only reproduces on the edit-then-distinguish path; distinguishing
a freshly created comment (edited: false) works.
Reproduction
const comment = await post.addComment({ text: 'hello' });
await comment.distinguish(true); // OK — edited is false
const edited = await comment.edit({ text: 'hello (edited)' });
await edited.distinguish(true); // throws: 2 UNKNOWN ... invalid value for bool field value: <timestamp>
Impact
- The RPC rejects, but the distinguish is applied on Reddit — the error is raised while
marshaling the post-action comment JSON that Reddit returned, i.e. after the action succeeded.
Apps get a spurious failure for an operation that worked, and the model fields the SDK updates from
the response (distinguishedBy, stickied) are never populated.
- Affects any thing that has ever been edited (the
edited timestamp is permanent), for every RPC
whose response is JsonRedditObjects / RedditObject: Moderation.Distinguish (comments and
posts, including undistinguish / distinguishAsAdmin) and LinksAndComments.EditCustomPost.
- Any app that maintains a pinned/sticky bot comment by editing it in place and re-distinguishing
will log this failure deterministically.
Expected behavior / suggested fix
RedditObject.edited should accommodate Reddit's false | float union — e.g. type it as
google.protobuf.Value, or as a double with false normalized to unset — or the gateway should
coerce edited to truthiness before marshaling the response.
Workaround in the meantime
Treat distinguish failures matching invalid value for bool field value: <number> as
likely-succeeded (optionally verify by re-fetching the comment and checking stickied /
distinguishedBy).
This bug was diagnosed and this report written by Claude (Claude Code, Anthropic), working from the app's production logs and the installed @devvit packages, at the app maintainer's request.
Summary
Calling
comment.distinguish(true)on a comment that has ever been edited rejects with a gRPCstatus-2 error from the platform, even though the distinguish/sticky is actually applied on Reddit.
The root cause is a protobuf contract mismatch: Reddit's API returns
editedasfalseor a floatepoch timestamp, but Devvit's
RedditObject.editedis declaredgoogle.protobuf.BoolValue, so thegateway fails to marshal the (successful) response.
Environment
confessor-mod, installed on r/confession@devvit/web0.13.6 (@devvit/protos0.13.6; flaw still present in latest@devvit/protos0.13.10)Observed error
Note
1785222440.0= 2026-07-28T07:07:20Z — the exact time the app had just edited the commentbefore distinguishing it. It is the comment's
editedtimestamp, not anything the app passed: theapp called
comment.distinguish(true)with a literal boolean, and@devvit/reddit'sComment.distinguishsends only{ id, how: 'yes', sticky: true }, which matchesDistinguishRequest(moderation_msg.d.ts:65-72). The failure is in the response path.Root cause
Moderation.DistinguishreturnsJsonRedditObjects(moderation_svc.d.ts:34), whosethings[].dataisRedditObject(common/common_msg.d.ts). In that message:approvedAtUtc,bannedAtUtc,created,createdUtcare correctly typed as numbers, buteditedis declared as a bool wrapper:edited?: boolean | undefined(common_msg.d.ts:207-208),encoded as
google.protobuf.BoolValue(common_msg.js:841-842:BoolValue.encode({ value: message.edited }, ...)).Reddit's API returns
edited: falsefor never-edited things andedited: <float epoch>for editedthings. When the gateway converts Reddit's JSON response for a distinguish call into the proto, an
edited comment's timestamp cannot unmarshal into
BoolValue— hence the Go protojson error namingthe wrapper's inner field:
invalid value for bool field value: 1785222440.0.Consistent with this, the error only reproduces on the edit-then-distinguish path; distinguishing
a freshly created comment (
edited: false) works.Reproduction
Impact
marshaling the post-action comment JSON that Reddit returned, i.e. after the action succeeded.
Apps get a spurious failure for an operation that worked, and the model fields the SDK updates from
the response (
distinguishedBy,stickied) are never populated.editedtimestamp is permanent), for every RPCwhose response is
JsonRedditObjects/RedditObject:Moderation.Distinguish(comments andposts, including
undistinguish/distinguishAsAdmin) andLinksAndComments.EditCustomPost.will log this failure deterministically.
Expected behavior / suggested fix
RedditObject.editedshould accommodate Reddit'sfalse | floatunion — e.g. type it asgoogle.protobuf.Value, or as a double withfalsenormalized to unset — or the gateway shouldcoerce
editedto truthiness before marshaling the response.Workaround in the meantime
Treat distinguish failures matching
invalid value for bool field value: <number>aslikely-succeeded (optionally verify by re-fetching the comment and checking
stickied/distinguishedBy).This bug was diagnosed and this report written by Claude (Claude Code, Anthropic), working from the app's production logs and the installed
@devvitpackages, at the app maintainer's request.