Skip to content

warpdroid: align timeline display with desktop frontend#164

Merged
filinvadim merged 6 commits intodevelopfrom
claude/android-private-key-generation-eJFnh
May 4, 2026
Merged

warpdroid: align timeline display with desktop frontend#164
filinvadim merged 6 commits intodevelopfrom
claude/android-private-key-generation-eJFnh

Conversation

@filinvadim
Copy link
Copy Markdown
Member

@filinvadim filinvadim commented May 3, 2026

Summary

Three regressions in the Android timeline path versus the Vue desktop frontend.

1. Counts hard-coded to zero in the timeline

WarpnetMapper.toStatus baselined like / retweet / reply / view counts at 0 and WarpnetRepository.hydrateStatuses never called the stats endpoint. The home and profile feeds therefore showed 0 / 0 / 0 under every tweet, while the desktop showed real counts.

hydrateStatuses now fans PUBLIC_GET_TWEET_STATS across all tweets in parallel via coroutineScope { … async { … } } (de-duped by tweet id, since retweets reuse the original id) and merges the result into each Status with .copy(…). A failed stats RPC degrades silently to zero, matching the existing toStatus baseline. When the local node is unpaired (viewerId.isBlank()) the fanout is skipped entirely; the backend would reject empty user_id anyway. Long → Int is clamped to defend the UI against an overflowed counter.

2. @-handle rendered the friendly username

Desktop prints the long peer-derived user_id (@01KQJF…); Android was printing @Vadim. WarpnetMapper.{toAccount, toTimelineAccount, stubTimelineAccount} now set localUsername = id, username = id, and keep displayName = username. Mastodon-shaped UI code that resolves @ now produces the same handle the desktop does.

3. Posts silently disappeared

The actual fix lives in SendStatusService.failOrRetry. The Tusky original branched on HttpException to decide between failSending (visible error notification) and retrySending (linear backoff). Warpnet has no HTTP layer and so never throws HttpException — every transport failure routed to retrySending and looped forever, so a libp2p flap during posting was indistinguishable from "nothing happened".

failOrRetry is now bounded: retry up to MAX_SEND_RETRIES (5), then fall through to failSending so the user sees the error notification and the draft is preserved. Empty created_at on the wire is intentional — the Go backend's CreateWithTTL already substitutes time.Now() when tweet.CreatedAt.IsZero().

Test plan

  • Open the home tab on a paired device, confirm reply / retweet / like counts under each tweet match the desktop frontend.
  • Open the home tab, confirm @<peer-id> is shown next to the friendly display name.
  • Compose a tweet from the mobile, confirm it appears on the desktop timeline within seconds.
  • Compose a tweet while the mobile is offline / network-flapping, confirm an error notification appears after the retry budget is exhausted (instead of the post vanishing).

https://claude.ai/code/session_01QLKpuj54ZBVqXd17R1v6ty


Generated by Claude Code

Three regressions versus the Vue frontend, all in the timeline path:

* Tweet stats (likes / retweets / replies / views) were hard-coded to 0
  in WarpnetMapper.toStatus and never refreshed when hydrating the home
  feed. Fetch PUBLIC_GET_TWEET_STATS for each tweet in parallel during
  hydrateStatuses and merge the counts into the Status.

* The @-handle rendered the friendly username ("@vadim") instead of
  the canonical peer-derived user_id that the desktop prints
  ("@01KQJF..."). Switch WarpnetMapper.{toAccount,toTimelineAccount,
  stubTimelineAccount} so localUsername/username carry the user_id
  and displayName carries the friendly username.

* Posts from the mobile silently failed because postStatus sent
  created_at = "" and json-iterator rejects the empty string before
  TweetRepo.Create's zero-time fallback runs. Send the current
  RFC3339 timestamp instead.
@codecov-commenter
Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

claude added 2 commits May 3, 2026 18:25
The previous fix in this PR sent Instant.now().toString() to dodge a
json-iterator decode error on the empty-string created_at. The right
fix is to leave the field absent so the backend's
TweetRepo.CreateWithTTL fallback (database/tweet-repo.go:152) stamps
time.Now() on the server side.

Make WarpnetTweet.createdAt nullable with default null; postStatus and
reblogStatus drop their explicit "" assignments. json-iterator decodes
null and missing into a zero time.Time, which the repo overwrites.
The empty string is the only encoding that fails decode; we no longer
emit it.
Logs from a paired session show no decode error from
/private/post/tweet/0.0.0, so the empty-string created_at theory was
wrong. Restore WarpnetTweet.createdAt to non-nullable, restore the
postStatus and reblogStatus payloads, restore parseDate's signature.

Stats hydration and the @-handle changes earlier in this PR remain;
those are independent and visibly broken in the screenshots.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 3, 2026

CI build failure (bfa93ac)

Run: https://github.com/Warp-net/warpnet/actions/runs/25287123587

:app:assembleDebug (last 60 KB)
string/tusky_compose_post_quicksetting_label without required default value.

warn: removing resource site.warpnet.warpdroid:string/about_powered_by_tusky without required default value.
warn: removing resource site.warpnet.warpdroid:string/about_tusky_account without required default value.
warn: removing resource site.warpnet.warpdroid:string/about_tusky_license without required default value.
warn: removing resource site.warpnet.warpdroid:string/about_tusky_version without required default value.
warn: removing resource site.warpnet.warpdroid:string/tusky_compose_post_quicksetting_label without required default value.

warn: removing resource site.warpnet.warpdroid:string/about_powered_by_tusky without required default value.
warn: removing resource site.warpnet.warpdroid:string/about_tusky_account without required default value.
warn: removing resource site.warpnet.warpdroid:string/about_tusky_license without required default value.
warn: removing resource site.warpnet.warpdroid:string/about_tusky_version without required default value.
warn: removing resource site.warpnet.warpdroid:string/tusky_compose_post_quicksetting_label without required default value.

> Task :app:processBlueDebugResources
> Task :warpnet-transport:checkKotlinGradlePluginConfigurationErrors SKIPPED
> Task :warpnet-transport:kspDebugKotlin

> Task :warpnet-transport:compileDebugKotlin
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/AuthNodeInfo.kt:20:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/AuthNodeInfo.kt:21:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/AuthNodeInfo.kt:22:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/AuthNodeInfo.kt:23:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/AuthNodeInfo.kt:24:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/AuthNodeInfo.kt:25:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/AuthNodeInfo.kt:26:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:32:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:33:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:34:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:35:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:36:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:38:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:40:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:50:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:51:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:52:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:53:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:54:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:55:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:56:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:57:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:58:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:66:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:68:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:69:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:78:25 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:82:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:89:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:90:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:95:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:96:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:103:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:104:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:109:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:110:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:115:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:116:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:133:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:134:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:135:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:140:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:141:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:146:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:147:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:152:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:153:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:158:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:165:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:172:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:186:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:191:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:230:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:241:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:248:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:255:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:262:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:267:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:272:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:277:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:278:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:279:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:280:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:281:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.
w: file:///home/runner/work/warpnet/warpnet/warpdroid/warpnet-transport/src/main/kotlin/site/warpnet/transport/dto/WarpnetDtos.kt:282:5 This annotation is currently applied to the value parameter only, but in the future it will also be applied to property.
- To opt in to applying to both value parameter and property, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.

See https://youtrack.jetbrains.com/issue/KT-73255 for more details.

> Task :warpnet-transport:javaPreCompileDebug
> Task :warpnet-transport:compileDebugJavaWithJavac NO-SOURCE
> Task :warpnet-transport:bundleLibCompileToJarDebug
> Task :app:kspBlueDebugKotlin

> Task :app:compileBlueDebugKotlin FAILED
e: file:///home/runner/work/warpnet/warpnet/warpdroid/app/src/main/java/site/warpnet/warpdroid/warpnet/WarpnetMapper.kt:74:35 Argument type mismatch: actual type is 'String?', but 'String' was expected.
gradle/actions: Writing build results to /home/runner/work/_temp/.gradle-actions/build-results/build-1777832732774.json

[Incubating] Problems report is available at: file:///home/runner/work/warpnet/warpnet/warpdroid/build/reports/problems/problems-report.html

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:compileBlueDebugKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction
   > Compilation error. See log for more details

* Try:
> Run with --info or --debug option to get more log output.
> Get more help at https://help.gradle.org.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:compileBlueDebugKotlin'.
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:135)
	at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:288)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:133)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:121)
	at org.gradle.api.internal.tasks.execution.ProblemsTaskPathTrackingTaskExecuter.execute(ProblemsTaskPathTrackingTaskExecuter.java:41)
	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:74)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:45)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:347)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:334)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.lambda$execute$0(DefaultTaskExecutionGraph.java:330)
	at org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:84)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:330)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:319)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:459)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:376)
	at org.gradle.execution.plan.DefaultPlanExecutor.process(DefaultPlanExecutor.java:111)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph.executeWithServices(DefaultTaskExecutionGraph.java:144)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph.execute(DefaultTaskExecutionGraph.java:129)
	at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:35)
	at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:51)
	at org.gradle.execution.BuildOperationFiringBuildWorkerExecutor$ExecuteTasks.call(BuildOperationFiringBuildWorkerExecutor.java:54)
	at org.gradle.execution.BuildOperationFiringBuildWorkerExecutor$ExecuteTasks.call(BuildOperationFiringBuildWorkerExecutor.java:43)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.execution.BuildOperationFiringBuildWorkerExecutor.execute(BuildOperationFiringBuildWorkerExecutor.java:40)
	at org.gradle.internal.build.DefaultBuildLifecycleController.lambda$executeTasks$10(DefaultBuildLifecycleController.java:313)
	at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:266)
	at org.gradle.internal.model.StateTransitionController.lambda$tryTransition$8(StateTransitionController.java:177)
	at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:45)
	at org.gradle.internal.model.StateTransitionController.tryTransition(StateTransitionController.java:177)
	at org.gradle.internal.build.DefaultBuildLifecycleController.executeTasks(DefaultBuildLifecycleController.java:304)
	at org.gradle.internal.build.DefaultBuildWorkGraphController$DefaultBuildWorkGraph.runWork(DefaultBuildWorkGraphController.java:220)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:263)
	at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
	at org.gradle.composite.internal.DefaultBuildController.doRun(DefaultBuildController.java:181)
	at org.gradle.composite.internal.DefaultBuildController.access$000(DefaultBuildController.java:50)
	at org.gradle.composite.internal.DefaultBuildController$BuildOpRunnable.lambda$run$0(DefaultBuildController.java:198)
	at org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:84)
	at org.gradle.composite.internal.DefaultBuildController$BuildOpRunnable.run(DefaultBuildController.java:198)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
Caused by: org.gradle.workers.internal.DefaultWorkerExecutor$WorkExecutionException: A failure occurred while executing org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction
	at org.gradle.workers.internal.DefaultWorkerExecutor$WorkItemExecution.waitForCompletion(DefaultWorkerExecutor.java:289)
	at org.gradle.internal.work.DefaultAsyncWorkTracker.lambda$waitForItemsAndGatherFailures$2(DefaultAsyncWorkTracker.java:130)
	at org.gradle.internal.Factories$1.create(Factories.java:31)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withoutLocks(DefaultWorkerLeaseService.java:335)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withoutLocks(DefaultWorkerLeaseService.java:318)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withoutLock(DefaultWorkerLeaseService.java:323)
	at org.gradle.internal.work.DefaultAsyncWorkTracker.waitForItemsAndGatherFailures(DefaultAsyncWorkTracker.java:126)
	at org.gradle.internal.work.DefaultAsyncWorkTracker.waitForItemsAndGatherFailures(DefaultAsyncWorkTracker.java:92)
	at org.gradle.internal.work.DefaultAsyncWorkTracker.waitForAll(DefaultAsyncWorkTracker.java:78)
	at org.gradle.internal.work.DefaultAsyncWorkTracker.waitForCompletion(DefaultAsyncWorkTracker.java:66)
	at org.gradle.api.internal.tasks.execution.TaskExecution$3.run(TaskExecution.java:260)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
	at org.gradle.api.internal.tasks.execution.TaskExecution.executeAction(TaskExecution.java:237)
	at org.gradle.api.internal.tasks.execution.TaskExecution.executeActions(TaskExecution.java:220)
	at org.gradle.api.internal.tasks.execution.TaskExecution.executeWithPreviousOutputFiles(TaskExecution.java:203)
	at org.gradle.api.internal.tasks.execution.TaskExecution.execute(TaskExecution.java:170)
	at org.gradle.internal.execution.steps.ExecuteStep.executeInternal(ExecuteStep.java:105)
	at org.gradle.internal.execution.steps.ExecuteStep.access$000(ExecuteStep.java:44)
	at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:59)
	at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:56)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:56)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:44)
	at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:42)
	at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:75)
	at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:55)
	at org.gradle.internal.execution.steps.PreCreateOutputParentsStep.execute(PreCreateOutputParentsStep.java:50)
	at org.gradle.internal.execution.steps.PreCreateOutputParentsStep.execute(PreCreateOutputParentsStep.java:28)
	at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:68)
	at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:38)
	at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:61)
	at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:26)
	at org.gradle.internal.execution.steps.CaptureOutputsAfterExecutionStep.execute(CaptureOutputsAfterExecutionStep.java:69)
	at org.gradle.internal.execution.steps.CaptureOutputsAfterExecutionStep.execute(CaptureOutputsAfterExecutionStep.java:46)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:39)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:28)
	at org.gradle.internal.execution.steps.BuildCacheStep.executeWithoutCache(BuildCacheStep.java:189)
	at org.gradle.internal.execution.steps.BuildCacheStep.executeAndStoreInCache(BuildCacheStep.java:145)
	at org.gradle.internal.execution.steps.BuildCacheStep.lambda$executeWithCache$4(BuildCacheStep.java:101)
	at org.gradle.internal.execution.steps.BuildCacheStep.lambda$executeWithCache$5(BuildCacheStep.java:101)
	at org.gradle.internal.Try$Success.map(Try.java:170)
	at org.gradle.internal.execution.steps.BuildCacheStep.executeWithCache(BuildCacheStep.java:85)
	at org.gradle.internal.execution.steps.BuildCacheStep.lambda$execute$0(BuildCacheStep.java:74)
	at org.gradle.internal.Either$Left.fold(Either.java:116)
	at org.gradle.internal.execution.caching.CachingState.fold(CachingState.java:62)
	at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:73)
	at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:48)
	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:46)
	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:35)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:75)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$2(SkipUpToDateStep.java:53)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:53)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:35)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:37)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:27)
	at org.gradle.internal.execution.steps.ResolveIncrementalCachingStateStep.executeDelegate(ResolveIncrementalCachingStateStep.java:49)
	at org.gradle.internal.execution.steps.ResolveIncrementalCachingStateStep.executeDelegate(ResolveIncrementalCachingStateStep.java:27)
	at org.gradle.internal.execution.steps.AbstractResolveCachingStateStep.execute(AbstractResolveCachingStateStep.java:71)
	at org.gradle.internal.execution.steps.AbstractResolveCachingStateStep.execute(AbstractResolveCachingStateStep.java:39)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:64)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:35)
	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:62)
	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:40)
	at org.gradle.internal.execution.steps.AbstractCaptureStateBeforeExecutionStep.execute(AbstractCaptureStateBeforeExecutionStep.java:76)
	at org.gradle.internal.execution.steps.AbstractCaptureStateBeforeExecutionStep.execute(AbstractCaptureStateBeforeExecutionStep.java:45)
	at org.gradle.internal.execution.steps.AbstractSkipEmptyWorkStep.executeWithNonEmptySources(AbstractSkipEmptyWorkStep.java:136)
	at org.gradle.internal.execution.steps.AbstractSkipEmptyWorkStep.execute(AbstractSkipEmptyWorkStep.java:66)
	at org.gradle.internal.execution.steps.AbstractSkipEmptyWorkStep.execute(AbstractSkipEmptyWorkStep.java:38)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:36)
	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:23)
	at org.gradle.internal.execution.steps.HandleStaleOutputsStep.execute(HandleStaleOutputsStep.java:75)
	at org.gradle.internal.execution.steps.HandleStaleOutputsStep.execute(HandleStaleOutputsStep.java:41)
	at org.gradle.internal.execution.steps.AssignMutableWorkspaceStep.lambda$execute$0(AssignMutableWorkspaceStep.java:35)
	at org.gradle.api.internal.tasks.execution.TaskExecution$4.withWorkspace(TaskExecution.java:297)
	at org.gradle.internal.execution.steps.AssignMutableWorkspaceStep.execute(AssignMutableWorkspaceStep.java:31)
	at org.gradle.internal.execution.steps.AssignMutableWorkspaceStep.execute(AssignMutableWorkspaceStep.java:22)
	at org.gradle.internal.execution.steps.ChoosePipelineStep.execute(ChoosePipelineStep.java:40)
	at org.gradle.internal.execution.steps.ChoosePipelineStep.execute(ChoosePipelineStep.java:23)
	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.lambda$execute$2(ExecuteWorkBuildOperationFiringStep.java:67)
	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.execute(ExecuteWorkBuildOperationFiringStep.java:67)
	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.execute(ExecuteWorkBuildOperationFiringStep.java:39)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:46)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:34)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:47)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:34)
	at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:64)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:132)
	... 58 more
Caused by: org.jetbrains.kotlin.gradle.tasks.CompilationErrorException: Compilation error. See log for more details
	at org.jetbrains.kotlin.gradle.tasks.TasksUtilsKt.throwExceptionIfCompilationFailed(tasksUtils.kt:21)
	at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:119)
	at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
	at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
	at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:66)
	at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:62)
	at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:100)
	at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:62)
	at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
	at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
	at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:59)
	at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
	at org.gradle.internal.Factories$1.create(Factories.java:31)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:263)
	at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
	at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
	... 2 more


Deprecated Gradle features were used in this build, making it incompatible with Gradle 10.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

For more on this, please refer to https://docs.gradle.org/9.0.0/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.

BUILD FAILED in 4m 4s
33 actionable tasks: 33 executed

Publishing build scan...
gradle/actions: Writing build results to /home/runner/work/_temp/.gradle-actions/build-scans/build-1777832732774.json
https://gradle.com/s/jjc6bpk5ovhaw

Configuration cache entry stored.

failOrRetry was a Tusky branch on HttpException; Warpnet never throws
that, so every transport failure looped silently in retrySending and
the post just disappeared. Cap at MAX_SEND_RETRIES (5) and fall through
to failSending so the user sees an error notification.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Aligns Warpdroid’s timeline/status rendering with the desktop frontend by hydrating tweet stats, normalizing how user handles are mapped into Mastodon-shaped models, and tightening status-send retry behavior.

Changes:

  • Fetch per-tweet stats in parallel during timeline hydration and merge counts into Status.
  • Map Account / TimelineAccount usernames to the peer-derived user_id so @<id> matches desktop.
  • Adjust send retry logic and bump the repo version.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
warpdroid/app/src/main/java/site/warpnet/warpdroid/warpnet/WarpnetRepository.kt Parallel tweet-stats fanout during timeline hydration; merge stats into Status.
warpdroid/app/src/main/java/site/warpnet/warpdroid/warpnet/WarpnetMapper.kt Change handle mapping so username / localUsername use id for @... parity with desktop.
warpdroid/app/src/main/java/site/warpnet/warpdroid/service/SendStatusService.kt Remove HTTP-specific retry branch and add bounded retry limit constant.
version Bump version string.
Comments suppressed due to low confidence (1)

warpdroid/app/src/main/java/site/warpnet/warpdroid/service/SendStatusService.kt:326

  • The KDoc for failOrRetry says it uses "exponential backoff", but retrySending() currently uses a linear backoff of retries seconds (capped). Either update the implementation to exponential (e.g., 2^retries) or adjust the comment so it matches the actual behavior.
    /**
     * Retry transient transport failures with exponential backoff up to
     * MAX_SEND_RETRIES, then surface a user-visible error notification.
     *
     * Warpnet never throws HttpException (no HTTP), so the original
     * Tusky branch on HttpException always fell through to retrySending
     * which busy-looped silently. Replace it with a bounded retry that
     * has to either land or fail loudly - "post or throw", no third
     * option.
     */
    private suspend fun failOrRetry(throwable: Throwable, statusId: Int) {
        val statusToSend = statusesToSend[statusId] ?: return
        if (statusToSend.retries >= MAX_SEND_RETRIES) {
            Log.w(TAG, "giving up on status $statusId after ${statusToSend.retries} retries", throwable)
            failSending(statusId)
            return
        }
        retrySending(statusId)
    }

    private suspend fun retrySending(statusId: Int) {
        // when statusToSend == null, sending has been canceled
        val statusToSend = statusesToSend[statusId] ?: return

        val backoff = TimeUnit.SECONDS.toMillis(
            statusToSend.retries.toLong()
        ).coerceAtMost(MAX_RETRY_INTERVAL)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 462 to 469
favouritesCount = s.likesCount.toInt(),
reblogsCount = s.retweetsCount.toInt(),
repliesCount = s.repliesCount.toInt(),
viewsCount = s.viewsCount.toInt(),
)
}
}

Comment thread version
Comment on lines +2 to +3


Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The trailing blank lines were already in version before this PR (the file has been a version line + 3 newlines for several releases). This PR's diff is only 0.6.3020.6.304; the trailing whitespace is unchanged.


Generated by Claude Code

Comment on lines +452 to +456
val viewerId = pairedNodeStore.load()?.userId.orEmpty()
val stats = tweets.associate { t ->
t.id to async {
runCatching { getTweetStats(tweetId = t.id, userId = viewerId) }.getOrNull()
}
Comment on lines +446 to +449
private suspend fun hydrateStatuses(tweets: List<WarpnetTweet>): List<Status> = coroutineScope {
if (tweets.isEmpty()) return@coroutineScope emptyList()
val cache = mutableMapOf<String, WarpnetUser>()
return tweets.map { t -> t.toStatus(resolveUser(t.userId, cache)) }
// Stats are fetched per tweet in parallel so a 30-tweet timeline
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not the bug — the Go backend's tweet-create path runs through CreateWithTTL, which has a time.Time.IsZero() → time.Now() fallback. Empty created_at is normalised server-side, so this is intentional. The actual silent-post regression was in SendStatusService.failOrRetry (no bounded retry on non-HttpException paths); fix is in the latest commit on this PR.


Generated by Claude Code

- WarpnetRepository: clamp stats Long->Int via clampToInt() so an
  overflowed counter doesn't render as a negative number, and
  short-circuit hydrateStatuses when viewerId is blank to avoid a
  per-tweet RPC fanout that the backend would just reject.
- SendStatusService: KDoc said "exponential backoff" but
  retrySending uses linear; align the comment.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +300 to 318
/**
* Retry transient transport failures with linear backoff up to
* MAX_SEND_RETRIES, then surface a user-visible error notification.
*
* Warpnet never throws HttpException (no HTTP), so the original
* Tusky branch on HttpException always fell through to retrySending
* which busy-looped silently. Replace it with a bounded retry that
* has to either land or fail loudly - "post or throw", no third
* option.
*/
private suspend fun failOrRetry(throwable: Throwable, statusId: Int) {
if (throwable is HttpException) {
// the server refused to accept, save status & show error message
val statusToSend = statusesToSend[statusId] ?: return
if (statusToSend.retries >= MAX_SEND_RETRIES) {
Log.w(TAG, "giving up on status $statusId after ${statusToSend.retries} retries", throwable)
failSending(statusId)
} else {
// a network problem occurred, let's retry sending the status
retrySending(statusId)
return
}
retrySending(statusId)
}
Comment on lines +312 to 314
if (statusToSend.retries >= MAX_SEND_RETRIES) {
Log.w(TAG, "giving up on status $statusId after ${statusToSend.retries} retries", throwable)
failSending(statusId)
Comment on lines +456 to +460
val stats = tweets.associate { t ->
t.id to async {
runCatching { getTweetStats(tweetId = t.id, userId = viewerId) }.getOrNull()
}
}
Comment on lines +300 to +308
/**
* Retry transient transport failures with linear backoff up to
* MAX_SEND_RETRIES, then surface a user-visible error notification.
*
* Warpnet never throws HttpException (no HTTP), so the original
* Tusky branch on HttpException always fell through to retrySending
* which busy-looped silently. Replace it with a bounded retry that
* has to either land or fail loudly - "post or throw", no third
* option.
- failOrRetry: log "attempts" not "retries" (retries is incremented
  at the start of sendStatus, so it's the attempt count by the time
  failOrRetry reads it). Adjust KDoc to match the broader retry
  policy.
- hydrateStatuses: de-dup tweet ids before fanning out the stats
  RPC; retweets reuse the original id and would otherwise fire the
  same request twice.
@filinvadim filinvadim merged commit 6cd1775 into develop May 4, 2026
6 checks passed
@filinvadim filinvadim deleted the claude/android-private-key-generation-eJFnh branch May 4, 2026 19:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants