Appsmith Documentation Audit
Appsmith's docs are broad and well-organized — 412 pages with a real error-troubleshooting tree and clean internal links — but the reference layer is littered with copy-paste drift: self-contradicting property descriptions, a function whose name changes between pages, and code examples that throw when pasted.
1. Workflow function name changes between reference pages (significant)
Location: /workflows/reference/workflow-functions and /workflows/reference/workflow-queries
Problem: The functions reference defines assignRequest() (singular): "The assignRequest() function is an asynchronous function that is part of the workflows object..." The adjacent queries reference calls it assignRequests (plural) three times: "as defined while creating request using the assignRequests workflow function. For more information, see assignRequests" and "The resolution must match those specified while creating the request using the assignRequests workflow function."
Consequence: A developer (or an AI agent generating workflow code) who reads the queries page first will write appsmith.workflows.assignRequests(...) and get a runtime error, then search the docs for a function that doesn't exist under that name. Agents fail silently on exactly this kind of cross-page identifier drift.
The fix: Standardize on the actual function name (assignRequest) across both pages and make the "see assignRequests" reference a working link to the function's anchor.
2. Table widget reference contradicts itself about totalRecordsCount and misdescribes tableHeaders (significant)
Location: /reference/widgets/table (Reference properties)
Problem: The content property "Total Records" is defined as "a number value that is displayed in the table header to inform the user about the total number of records in the table." But the corresponding reference property totalRecordsCount is described on the same page as "Indicates the number of pages in server-side pagination." Records and pages are different numbers. Two entries below, tableHeaders — typed as an array — is described with a boolean's description: "Indicates whether the table headers are visible."
Consequence: Anyone wiring server-side pagination has to guess whether Table1.totalRecordsCount returns records or pages — getting it wrong breaks page math by a factor of pageSize. tableHeaders is effectively undocumented: the description belongs to a different property, so its actual shape and contents are unknowable from the docs.
The fix: Correct totalRecordsCount to describe the total record count, and write a real description for tableHeaders (what the array contains, when it's populated).
3. JS Objects page teaches variable re-assignment with a syntactically broken example (significant)
Location: /core-concepts/writing-code/javascript-editor-beta ("Variables in JS Objects")
Problem: The page's only variables example places setColorValue outside the exported object. Verbatim from the page's code block: export default { colorValue: "#4A90E2", ...};// Example of re-assigning the variablesetColorValue: (newColor) => { jsObjectName.colorValue = newColor;}; — the export default {...} is closed and then a bare setColorValue: (newColor) => {...}; follows at top level. The page itself states "a JSObject can only export one default object," which this snippet violates.
Consequence: This is the canonical page for Appsmith's core scripting concept. A developer or agent pasting the example gets code that doesn't define setColorValue on the JSObject at all — the documented pattern for updating JSObject state simply doesn't work as shown.
The fix: Move setColorValue inside the exported object and show the two snippets as one valid JSObject.
4. Built-in Moment example calls .format() on a string and throws (significant)
Location: /write-code/reference/Built-in-JS-Libraries (Moment section)
Problem: The sole Moment usage example is {{ moment(datePicker1.selectedDate.format('DD MMM')) }}. The parentheses are misplaced: .format() is invoked on datePicker1.selectedDate (an ISO date string, which has no .format method) instead of on the moment object. Correct form is moment(datePicker1.selectedDate).format('DD MMM').
Consequence: The one example for the most commonly used built-in library throws TypeError: datePicker1.selectedDate.format is not a function when copied. Date formatting is one of the top uses of Moment in Appsmith bindings, so this lands on beginners disproportionately.
The fix: Change the example to {{ moment(datePicker1.selectedDate).format('DD MMM') }}.
5. Multipart form-data example shows a URL-encoded result copy-pasted from the previous section (significant)
Location: /connect-data/reference/rest-api (Body → MULTIPART_FORM_DATA)
Problem: The MULTIPART_FORM_DATA example table lists keys user, filename, and file (a Filepicker file), but the "// result" block beneath it repeats the FORM_URLENCODED section's output verbatim: "query=arjun&limit=10&offset=20" — different keys, different values, and not multipart encoding at all.
Consequence: Developers debugging file uploads compare their request against a documented "result" that can never occur for a multipart request, sending them down the wrong path (and multipart upload is already the fiddliest body type, as the page's own Data Format tips acknowledge).
The fix: Replace the result block with a representative multipart payload (boundary, per-part headers) matching the user/filename/file example, or delete the result block.
6. "Disable telemetry" doesn't disable the documented always-on pings, and the env-var reference omits the caveat (significant)
Location: /product/telemetry and /getting-started/setup/environment-variables (Telemetry section)
Problem: The telemetry page documents that the keep-alive ping ("sends a keep-alive ping every 2 hours... collected irrespective of whether telemetry is turned on or off"), the server setup ping (also "irrespective of whether telemetry is turned on or off" — its sample payload includes the server's ipAddress), and billing usage pulses ("collected only for paying customers, regardless of whether telemetry is on or off") all continue after opting out. Yet the same page opens its opt-out section with "Sharing telemetry is optional," and the environment-variables reference describes APPSMITH_DISABLE_TELEMETRY with no caveat: "You can configure this environment variable to enable or disable anonymous usage data collection."
Consequence: Self-hosters in restricted or compliance-sensitive environments set APPSMITH_DISABLE_TELEMETRY=true believing outbound data collection stops; per Appsmith's own docs, pings to cloud services continue every 2 hours. Anyone auditing egress from the env-var page alone gets a wrong answer.
The fix: State on both pages exactly which transmissions APPSMITH_DISABLE_TELEMETRY stops and which continue regardless, and reconcile "sharing telemetry is optional" with the always-on ping documentation.
7. No llms.txt or machine-readable docs index (significant)
Location: https://docs.appsmith.com/llms.txt and /llms-full.txt (both HTTP 404)
Problem: The site ships neither llms.txt nor llms-full.txt; both paths return 404 pages. The 412-page corpus is only discoverable via sitemap.xml and HTML crawling, and reference material (widget properties, framework functions, env vars) exists only as prose/HTML — there is no machine-readable export.
Consequence: AI coding agents — heavy consumers of low-code platform docs — must crawl and parse 412 HTML pages to answer questions like "what does Table1.totalRecordsCount return", amplifying the impact of the copy-paste drift found elsewhere in this audit, since agents can't cheaply cross-check pages.
The fix: Publish llms.txt (index) and llms-full.txt at the docs root; Docusaurus has established plugins for generating both from the existing MDX source.
8. Fetch API POST example logs a pending Promise while the PUT example on the same page does it right (minor)
Location: /write-code/reference/Fetch-API
Problem: The POST example ends with .then((response) => { console.log("Success:", response.json()); }) — response.json() returns a Promise, so this logs Promise {<pending>}, never the created resource. The PUT example immediately below handles it correctly with return response.json() and a chained .then((data) => ...).
Consequence: Developers copying the POST snippet to verify their integration see a pending Promise instead of their data and assume the request failed.
The fix: Align the POST example with the PUT example's promise chaining.
9. setInterval() signature declares an args parameter that is never documented (minor)
Location: /reference/appsmith-framework/widget-actions/intervals-time-events
Problem: The signature is setInterval(callbackFunction: Function, interval: number, id?: string, args?: any), but the Parameters section documents only callbackFunction, interval, and id. args appears nowhere else on the page and in no example.
Consequence: Developers can't tell whether args is forwarded to the callback (as in browser setInterval), ignored, or something else — the only way to find out is to experiment.
The fix: Document args (type, behavior, example) or remove it from the signature.
10. PostgreSQL SSL "Disable" option description contains an unrelated sentence (minor)
Location: /connect-data/reference/querying-postgres (SSL Mode)
Problem: The Disable option reads: "Only try a non-SSL connection. Disallows all administrative requests over HTTPS. It uses a plain unencrypted connection." The middle sentence — "Disallows all administrative requests over HTTPS" — has nothing to do with a Postgres client SSL mode; it appears to be pasted from a different product's setting.
Consequence: Readers deciding whether Disable is safe for an internal network get a spurious claim about HTTPS administrative requests that describes no actual behavior of this setting.
The fix: Delete the stray sentence.
11. Docker guide standardizes on the deprecated Compose v1 CLI and obsolete version key (minor)
Location: /getting-started/setup/installation-guides/docker
Problem: Prerequisites ask for "Docker-Compose(version 1.29.2 or later)" and every command uses the v1 docker-compose binary; the sample file begins with version: "3", which current Compose marks obsolete. Compose v1 stopped receiving updates in 2023 and is absent from modern Docker installs.
Consequence: Users on a current Docker Desktop/Engine hit docker-compose: command not found on the very first install command; the fix (docker compose) is nowhere on the page.
The fix: Use docker compose (v2 syntax) in prerequisites and commands, and drop the version key from the sample file.
12. Docs repo README's install command installs the wrong thing (minor)
Location: https://github.com/appsmithorg/appsmith-docs (README, linked as the contribution path from the docs)
Problem: The contributor setup instructions say "Run the below command to install node-modules: $ npm install package.json". That command asks npm to install a registry package named package.json, not the project's dependencies. The README also says the site is "powered by Docusaurus v2" while the live site's generator meta tag reports Docusaurus v3.6.3.
Consequence: First-time docs contributors — the audience this README exists for — start with a failing or misleading install step, raising the barrier for the community PRs the repo explicitly solicits.
The fix: Change to plain npm install and update the Docusaurus version reference.
What they do well
- A dedicated, deep troubleshooting tree (31 pages) with verbatim error strings — e.g. REST API errors quote the exact
DEFAULT_REST_DATASOURCE is not correctly configured...messages and their causes. - Internal link hygiene is excellent: a 163-link crawl across major pages found zero 404s (one clean 308 redirect).
- Honest, unusually detailed telemetry disclosure with full sample payloads — few vendors publish what their pings contain.
Top 3 recommendations
- Sweep the reference layer for copy-paste drift — the
assignRequest/assignRequestsmismatch, the Table property descriptions, and the multipart "result" block are all the same class of bug and are cheap to fix. - Lint code examples in CI: the JS Objects and Moment snippets would fail even a basic parse/execute check.
- Publish
llms.txt/llms-full.txtand align theAPPSMITH_DISABLE_TELEMETRYdocumentation across pages so both machines and compliance reviewers get one consistent answer.