Bug: Moderation.Distinguish fails on ever-edited comments — RedditObject.edited is BoolValue but Reddit returns a float timestamp

Open
#283 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
58/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
typescript

Research direction

Start with common/common_msg.d.ts and common/common_msg.js to inspect RedditObject.edited and its BoolValue encoding, then review moderation_svc.d.ts and moderation_msg.d.ts for the response path. Run the edit-then-distinguish reproduction. Done means edited comments no longer cause the response RPC to fail and the distinguish result still populates its model fields.

Written by the indexing model from the issue text.

Description

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.

Dominant language
TypeScript
Stars
210
Forks
88
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from reddit/devvit

All issues in reddit/devvit

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.