# MokuHub > MokuHub builds software for NetSuite and Salesforce teams and for field service businesses: MokuBot (an AI agent Chrome extension for NetSuite, with a Salesforce version in early access), MokuStudio (a free code editor for the NetSuite File Cabinet, shipped inside MokuBot) and MokuField (field service management for SMBs). The blog and the answers below are written for NetSuite administrators and developers. ## Products ### MokuBot: AI Agent for NetSuite URL: https://mokuhub.com/mokubot-netsuite Chrome extension that runs as a side panel inside an active NetSuite session. Describe a task in plain English; MokuBot executes it by chaining tool calls (querying metadata, running SuiteQL, creating records, deploying SuiteScripts) using the user's existing browser session, with no separate OAuth or REST setup. Key capabilities: - Natural-language SuiteQL: writes, executes, and explains queries - Saved Search creation from a description - SuiteScript generation, upload to File Cabinet, script-record creation, deployment - Execution-log analysis and error debugging - Read-Only mode by default; experimental write tools opt-in - No NetSuite bundle required (Chrome extension only) - Free 30-day trial, no payment card, all tools included, runs on fast AI models; paid plans (Pro, Pro+, Max) add the most capable models and more usage ### MokuStudio: Code Editor for the NetSuite File Cabinet URL: https://mokuhub.com/blog/netsuite-file-cabinet-code-editor Browser code editor that works directly on the File Cabinet of the NetSuite account you are signed in to. Open a file, edit it, save it back in place, with no download and re-upload. Ships inside the MokuBot Chrome extension and is free, with no subscription or plan required. Key capabilities: - Built on Monaco (the editor engine behind VS Code): folder tree, tabs, cross-file search, diff - JavaScript, TypeScript, JSON, HTML, CSS, XML and FreeMarker - Resolves SuiteScript define() dependencies from the File Cabinet, so autocomplete and type checks cover your own helper modules - Detects edits made on the server while you work and offers a three-way merge instead of overwriting - Shares a file system with the MokuBot agent, which sees unsaved changes in open tabs ### MokuBot for Salesforce URL: https://mokuhub.com/mokubot-salesforce The same agent for Salesforce, as a Chrome side panel next to the Salesforce tab, using the existing session. Currently in early access through a waitlist on the page. Key capabilities: - Plain English to SOQL/SOSL with result tables and CSV export - Create and update standard and custom records, with required-field checks - Apex classes, triggers, tests and Lightning Web Components, validated through the Tooling API and held for approval before deploy - Schema explorer: fields, picklists, record types, validation rules, relationships - Read-only by default; every write needs explicit approval ### MokuField: Field Service Management for SMBs URL: https://mokuhub.com/mokufield Field service management software for small and medium service businesses. Schedule and dispatch technicians, manage work orders, track GPS, capture signatures, and invoice from the field. Key capabilities: - Work order management with custom forms and checklists - Drag-and-drop scheduling and dispatch board - Native iOS and Android mobile apps with offline mode - Built-in GPS tracking via the mobile app (Google Maps) - QuickBooks Online integration (Xero and Zoho Books on roadmap) - CSV/JSON/PDF data export, no lock-in - AWS-hosted with per-organization database isolation ## Blog Long-form articles on NetSuite releases, SuiteScript, SuiteQL and finance operations. Index: https://mokuhub.com/blog - [NetSuite REST Saved Search: What It Runs and What It Won't](https://mokuhub.com/blog/netsuite-rest-saved-search-2026-2): NetSuite 2026.2 lets REST list and run saved searches. It cannot add filters or change sorting per request, which breaks many SOAP-era search integrations. - [Externally Rated Usage Billing in NetSuite 2026.2: The Dedup Is Your Job](https://mokuhub.com/blog/netsuite-2026-2-usage-billing-suitescript): NetSuite 2026.2 adds Use Usage Amount Only, so a third-party platform can price usage. The usage record takes no scripts, so the dedup lives outside it. - [NetSuite 2026.2 Changed the Default SuiteQL Sort Order: What It Breaks](https://mokuhub.com/blog/netsuite-suiteql-default-sort-order-2026-2): NetSuite 2026.2 switched the default sort for transaction SuiteQL from tranDisplayName to tranDate. Nothing errors, and paged reads break quietly. - [SuiteScript 1.0 to 2.1: Where an AI Conversion Runs Clean and Is Still Wrong](https://mokuhub.com/blog/netsuite-suitescript-1-to-2-1-agent-skill): Oracle's SuiteScript upgrade skill maps 1.0 calls to 2.1. The conversions worth reviewing are the ones that compile, deploy, and quietly change behavior. - [NetSuite SOAP and TBA Changes: What to Migrate Before 2027.1](https://mokuhub.com/blog/netsuite-soap-tba-rest-oauth-migration-2027-1): What 2027.1 blocks, when SOAP endpoints actually go dark, and how to separate the authentication migration from the API migration. - [NetSuite Next Access Control: What to Configure in 2026.2](https://mokuhub.com/blog/netsuite-next-access-control-2026-2): NetSuite 2026.2 controls NetSuite Next and Ask Oracle by role. What the three access modes mean, and what runtime.isNextActive() does not tell you. - [NetSuite SuiteScript Migration: Oracle Ships an AI Upgrade Assistant](https://mokuhub.com/blog/netsuite-suitescript-2-1-migration-2026-2): Oracle is pushing customers toward SuiteScript 2.1 with an AI migration skill. What the tool actually does, what it cannot do, and what the warning means. - [NetSuite 2026.2 Event Subscriber Scripts: What They Change for SuiteScript](https://mokuhub.com/blog/netsuite-event-subscriber-scripts-2026-2): NetSuite 2026.2 adds Event Subscriber scripts for asynchronous work after a record event. How they differ from User Events, and where the design bites. - [How Many NetSuite AI Units Do You Get, and How Long Do They Last?](https://mokuhub.com/blog/netsuite-next-ai-units-pricing): How many NetSuite AI Units a license includes, how the pool is shared, what each feature costs to run, and why the AI Connector does not consume any of them. - [NetSuite SOAP to REST Migration: What to Do and in What Order](https://mokuhub.com/blog/netsuite-soap-deprecation-rest-migration): SOAP dies in 2028.2. A phased plan for teams with real integrations: inventory, auth, records, searches, and the gaps that still have no clean answer. - [Why Your NetSuite AP Aging Never Ties to the General Ledger](https://mokuhub.com/blog/netsuite-ap-aging-does-not-match-gl): AP Aging and the payables balance disagree, and it is not a missing bill. Three traps in how NetSuite stores payables, with the SuiteQL that finds each one. - [Moving Work From Sandbox to Production Without an SDF Round Trip](https://mokuhub.com/blog/netsuite-sandbox-to-production-migration): What you built in sandbox is a file, a script record, a deployment, two fields and a search, and internal IDs do not survive the move. Use a manifest. - [The File Cabinet Has No Version Control, and It Does Not Tell You](https://mokuhub.com/blog/netsuite-file-cabinet-version-control): Two developers edit the same File Cabinet script. The second save destroys the first, with no warning and no history. Why it happens and how to detect it. - [MokuStudio: A Code Editor That Runs on Your NetSuite File Cabinet](https://mokuhub.com/blog/netsuite-file-cabinet-code-editor): The native File Cabinet editor is a textarea. MokuStudio runs the VS Code engine against your live File Cabinet, with IntelliSense over your own modules. - [What a NetSuite AI Agent Can Actually See](https://mokuhub.com/blog/netsuite-ai-agent-permissions): Three ways to put an AI agent into NetSuite, what each one can read, which role it acts under, and the audit trail problem the product pages do not mention. - [NetSuite Field Explorer: What It Does, and Where It Stops](https://mokuhub.com/blog/netsuite-field-explorer-vs-mokubot): Field Explorer reads the record, not the form, which is why the xml=T trick misses fields. What it shows, which forks are maintained, and where it stops. - [SuiteScript Governance: Why Your Script Works in Sandbox and Dies in Production](https://mokuhub.com/blog/suitescript-governance-limits-production): Governance units are a per-execution budget, not a rate limit. The arithmetic that decides whether your script survives, and the four cheapest substitutions. - [NetSuite Saved Search Formulas: What Breaks and Why](https://mokuhub.com/blog/netsuite-saved-search-formulas-what-breaks-and-why): A formula returns one number in Results and another in Summary. Why NULL swallows a CASE, what main line changes, and how to read a quiet failure. ## Answers Short answers to specific NetSuite errors and behaviours, each stated in the first paragraph of its page. Index: https://mokuhub.com/answers ### SuiteQL Answers Index: https://mokuhub.com/answers/suiteql #### Error messages, decoded - [SuiteQL syntax error near FETCH when FETCH is fine: NetSuite](https://mokuhub.com/answers/suiteql/suiteql-syntax-error-near-fetch-token-code-0): Your FETCH clause is probably fine. A column that does not exist on the table is the usual cause. Delete the FETCH FIRST clause, run the statement again, and the second error names the real problem. - [SuiteQL 'Unknown identifier' error in NetSuite, explained](https://mokuhub.com/answers/suiteql/suiteql-unknown-identifier-available-identifiers): The column does not exist on that table. Despite the wording, "Available identifiers" lists the table aliases in scope, not the columns you could have used. Adding a FETCH FIRST clause can hide this error behind a syntax error. - [NetSuite SuiteQL error 'Invalid or unsupported search'](https://mokuhub.com/answers/suiteql/suiteql-invalid-or-unsupported-search): A generic refusal carrying no error code, no position and no identifier name. In this run it came from CAST(id AS VARCHAR(20)), a date column compared to a bare ISO string, GROUPING SETS, and one RIGHT JOIN. - [N/query.runSuiteQL 'Unexpected Error' in NetSuite, explained](https://mokuhub.com/answers/suiteql/suiteql-unexpected-error-n-query-runsuiteql): It carries no code, no position and no identifier name. Read it as "something here is unsupported" and bisect the query. In this run it came from three BUILTIN calls and from a column that does not exist. - [How to list NetSuite tables and columns from SuiteQL](https://mokuhub.com/answers/suiteql/suiteql-invalid-search-type-oa-tables-no-catalog): You cannot. OA_TABLES and OA_COLUMNS are rejected with "Invalid search type", and ALL_TABLES, USER_TAB_COLUMNS and ALL_TAB_COLUMNS are absent too. For columns, run SELECT * with FETCH FIRST 1 ROWS ONLY; for custom records, query customrecordtype. - [Why CONNECT BY fails in NetSuite SuiteQL with no_root_node](https://mokuhub.com/answers/suiteql/suiteql-connect-by-start-with-no-root-node): START WITH CONNECT BY PRIOR fails at parse time here: a syntax error at the column inside START WITH, plus no_root_node. The statement does not reach execution, so LEVEL and SYS_CONNECT_BY_PATH stay untested. Build the tree yourself. #### Row limits and pagination - [Why LIMIT fails in NetSuite SuiteQL, and what to use instead](https://mokuhub.com/answers/suiteql/suiteql-limit-not-supported-row-limit-syntax): LIMIT is not in the SuiteQL dialect. Both engines reject it with a parse error pointing at the number after it. Use FETCH FIRST 5 ROWS ONLY; WHERE ROWNUM <= 5 and SELECT TOP 5 also worked. - [Why SuiteQL OFFSET returns page 1 again in NetSuite](https://mokuhub.com/answers/suiteql/suiteql-offset-clause-ignored-pagination): The SQL clause OFFSET n ROWS FETCH NEXT m ROWS ONLY has its OFFSET silently discarded on both engines, even with an explicit ORDER BY. Every page returns the first rows again. Paginate with the REST ?offset= parameter instead. - [Why SuiteQL REST totalResults does not match COUNT(*)](https://mokuhub.com/answers/suiteql/suiteql-totalresults-not-a-row-count): totalResults is not a row count. It reports min(rows your query returns, limit x 1000), so on a larger result set it reports the cap and calls it the total, HTTP 200, no flag. Run SELECT COUNT(*) separately. #### Dates and time - [SYSDATE vs CURRENT_DATE in NetSuite SuiteQL: why they differ](https://mokuhub.com/answers/suiteql/suiteql-sysdate-vs-current-date-timezone): Two different clocks. SYSDATE follows NetSuite's server clock, which read UTC-07:00 in this run; CURRENT_DATE and CURRENT_TIMESTAMP follow the calling session's timezone. They came back ten hours apart in the same row, with no error. - [Why NetSuite SuiteQL returns dates as 8/20/2026 with no time](https://mokuhub.com/answers/suiteql/suiteql-date-returned-as-m-d-yyyy-time-dropped): Date values serialise as M/D/YYYY in this run and any time component is dropped. The time is still in the column: select TO_CHAR(col,'YYYY-MM-DD HH24:MI:SS'). A TO_DATE mask parses input, it does not control output. - [How to compare a date to a literal in NetSuite SuiteQL](https://mokuhub.com/answers/suiteql/suiteql-date-literal-comparison-forms): TO_DATE('2026-01-01','YYYY-MM-DD'), DATE '2026-01-01' and the bare string '1/1/2026' all work and returned identical counts. The bare ISO string '2026-01-01' fails with "Invalid or unsupported search". BETWEEN with TO_DATE on both sides works. #### Joins and reconciliation - [Why a SuiteQL RIGHT JOIN to transactionLine returns 0 rows](https://mokuhub.com/answers/suiteql/suiteql-right-join-full-outer-silently-inner): RIGHT JOIN between transaction and transactionLine runs as an inner join and returns zero rows. FULL OUTER is downgraded to a LEFT join from the header. No error. LEFT JOIN from the header and Oracle (+) both work. - [Why a transactionAccountingLine join multiplies SuiteQL rows](https://mokuhub.com/answers/suiteql/suiteql-transactionaccountingline-join-fanout): You joined on transaction alone. transactionAccountingLine must match transactionLine on both transaction and line id. The transaction-only join matches every accounting line against every line of the same document, silently multiplying rows and any sum built on them. - [No subsidiary column on transactionAccountingLine in SuiteQL](https://mokuhub.com/answers/suiteql/suiteql-transactionaccountingline-no-subsidiary-column): There is no subsidiary column on transactionAccountingLine, and selecting it fails with a bare "Unexpected Error" that never names the column. Join transactionLine on both transaction and line id, then read subsidiary from there. - [Filter by a multi-select employee field in NetSuite SuiteQL](https://mokuhub.com/answers/suiteql/suiteql-multiselect-employee-filter): Do not filter the displayed multi-select column as a scalar value. Filter the generated MAP_ relationship table, then use its record IDs in the main query. #### What comes back - [Does BUILTIN.DF silently drop rows in NetSuite SuiteQL?](https://mokuhub.com/answers/suiteql/suiteql-builtin-df-does-not-drop-rows): No. Wrapping a column in BUILTIN.DF returned the same row count as the bare table in every form tested. The gap people see is COUNT(BUILTIN.DF(col)) skipping nulls, which is ordinary COUNT(expr) behaviour, not a row drop. - [Why NetSuite SuiteQL returns CustInvc instead of Invoice](https://mokuhub.com/answers/suiteql/suiteql-transaction-type-codes-custinvc-not-invoice): The type column holds internal codes: CustInvc, VendBill, ExpRept, CuTrSale, RevArrng and so on. A filter written against the display name Invoice matches no row. Use the code, or filter on BUILTIN.DF(type), which selected the same rows. - [Why SuiteQL lowercases quoted column aliases in NetSuite](https://mokuhub.com/answers/suiteql/suiteql-column-alias-lowercased-in-results): Returned JSON keys come back lowercased on both engines even when the alias is double-quoted. SELECT id AS "Transaction ID" returns the key "transaction id": the space survives, the capitals do not, so row["Transaction ID"] is undefined. ### Saved Search Answers Index: https://mokuhub.com/answers/saved-search #### Formulas that fail without erroring - [Saved search formula says ERROR: Field Not Found in NetSuite](https://mokuhub.com/answers/saved-search/saved-search-error-field-not-found-in-results-formula): Because the search succeeded. A field token in a Results formula did not resolve, and NetSuite writes the literal 22-character string "ERROR: Field Not Found" into the column as its value on every row. It is data, not an exception, it appears in Formula(Numeric) columns, it survives SUM, and NVL does not protect it. - [INVALID_FORMULA_FIELD in a NetSuite saved search, explained](https://mokuhub.com/answers/saved-search/saved-search-invalid-formula-field-criteria-error): It means a field token in your Criteria formula did not resolve, so NetSuite refused the search before running it. The Criteria side validates field names; the Results side does not, and the same typo there returns no error at all. Fix the token in braces, not the logic. - [Why {entity.internalid} fails in a NetSuite saved search](https://mokuhub.com/answers/saved-search/saved-search-entity-internalid-vs-entity-id): Because the token is {entity.id}. In a formula, internalid is not a resolvable name, and the failure is silent: the column fills with the literal string ERROR: Field Not Found on every row and the search reports success. One join level works with .id; two levels did not resolve in this run. - [{type} vs {type.id} in NetSuite saved search formulas](https://mokuhub.com/answers/saved-search/saved-search-display-name-vs-internal-code-in-formula): Because {field} gives the display name and {field.id} gives the internal code. They are two different strings for the same value. {field.name} does not exist and fails silently. Note the trap: SuiteQL returns the code by default where a saved search formula returns the label, so literals copied between the two engines match nothing. - [Does NVL fix nulls in a NetSuite saved search CASE WHEN?](https://mokuhub.com/answers/saved-search/saved-search-nvl-does-not-fix-null-in-case): No. Both versions were run and grouped, and the output was identical in every bucket, to the row. NVL turns null into 0, and 0 still fails > 0, so the row lands in the same ELSE. NVL only helps if the formula branches on the substituted value, as a first WHEN. #### What the formula type does to your number - [Formula (Percent) 100 times too big in NetSuite saved search](https://mokuhub.com/answers/saved-search/saved-search-formula-percent-multiplies-by-100): Because Formula (Percent) multiplies by 100 itself and appends a literal % sign. If your expression already computes a percentage, the column reports a hundred times the real figure with a plausible % on the end. Feed Percent the ratio and drop the *100. - [Why Formula (Numeric) returns 39 decimal places in NetSuite](https://mokuhub.com/answers/saved-search/saved-search-formula-numeric-decimal-places): Because Formula (Numeric) does not round at all. It hands back the raw Oracle NUMBER, which is what reaches your CSV export or SuiteScript variable, so 1/3 comes back with 39 decimal places. Formula (Currency) is not the fix: it rounded to 3 dp on some values and 2 on another. Use ROUND(x,2) in the expression. #### Counting rows and summary types - [Why NetSuite saved search Count is lower than the row count](https://mokuhub.com/answers/saved-search/saved-search-count-summary-is-count-distinct): Because Count is COUNT(DISTINCT), not a row count. It counts how many different values a column produces, so Count of {internalid} on a transaction search reports distinct transactions while the search returned lines. A Formula(Numeric) column of 1 summarised as Sum is the row count. - [How to count the rows a NetSuite saved search returns](https://mokuhub.com/answers/saved-search/saved-search-count-rows-with-sum-of-1): Add a Formula(Numeric) results column whose formula is the literal 1 and set its Summary to Sum. That total is the row count. Count does not give you one: it is COUNT(DISTINCT), so Count of {internalid} returns distinct transactions and Count of a constant returns 1. - [Invalid column summary type on a NetSuite search formula](https://mokuhub.com/answers/saved-search/saved-search-invalid-column-summary-type-formulatext-sum): You put Sum or Average on a Formula(Text) column. The message names the pair that failed, as in "formulatext: SUM.", under code SSS_INVALID_SRCH_COLUMN_SUM. Change the column to Formula(Numeric) or change the summary. Minimum and Maximum on a text formula are accepted and return a lexicographic result. #### Dates in formulas - [Why {today} - {trandate} returns decimals in NetSuite](https://mokuhub.com/answers/saved-search/saved-search-today-minus-trandate-not-whole-days): Because {today} is a timestamp, not a date. It carries the time of day, so the subtraction leaves a fraction of a day on the end and the result is never a whole number. An equality test against a day count never matches, and a greater-than test moves during the working day. Use TRUNC({today}) - {trandate}, which returns an integer. - [Group a NetSuite saved search by month with a formula](https://mokuhub.com/answers/saved-search/saved-search-group-dates-by-month-to-char-trunc): TO_CHAR({trandate},'YYYY-MM') in a Formula(Text) column gives a sortable month key and honours the format mask exactly. TRUNC({trandate},'MM') in a Formula(Date) column gives the first of the month as a real date, but it renders in the account's date format rather than ISO, so export the text version if anything downstream parses it. #### Filters and criteria - [Why equalto is not valid on internalid in NetSuite searches](https://mokuhub.com/answers/saved-search/saved-search-internalid-equalto-invalid-operator): Because NetSuite does not accept equalto on internalid: the filter is refused with SSS_INVALID_SRCH_OPERATOR and the search returns an error instead of rows. Use anyof, which takes an array and scales to a list. is also works, on a bare string, which is the part most people do not expect. - [Why Formula (Text) on internal id matches too many rows](https://mokuhub.com/answers/saved-search/saved-search-formula-text-contains-substring-match): Because a text formula makes every operator a string operator. Formula(Text) {internalid} contains '2' is a substring scan over the digits of the id, so it matches 2, 12, 20, 102 and everything else containing a 2. In the account tested it matched more than half the rows in the search, with no error. Use anyof, or Formula(Numeric). - [Can a formula be an Available Filter on a NetSuite search?](https://mokuhub.com/answers/saved-search/saved-search-available-filter-formula-has-no-expression): You can select one and you can never make it work. The Available Filters sublist has four columns, Filter, Show in Filter Region, Show as Multi-Select and Label, and none of them is a formula box. Criteria has a column literally labelled Formula; Available Filters does not. The search saves anyway, with no error, carrying a filter that has no expression in it. #### Fields missing from the search - [Custom field missing from NetSuite saved search field list](https://mokuhub.com/answers/saved-search/saved-search-custom-field-missing-from-field-list): Because the field is marked Inactive. That one checkbox on the custom field record, labelled exactly "Inactive", removes it from the Criteria, Results and Available Filters dropdowns at the same time. Store Value is not the cause, whatever the forum threads say: with Store Value off the field is still listed in all three. Display Type = HIDDEN and Applies To do not remove it either. - [Custom field blank on every row of a NetSuite saved search](https://mokuhub.com/answers/saved-search/saved-search-custom-field-blank-on-every-row): Because Store Value is unticked on the custom field record, so there is nothing stored for the search to return. The field stays fully usable: as a results column it runs and returns empty on every row, inside a formula the same, and as a criteria filter "is empty" matched every row in the table. Nothing errors, so the report looks structurally fine and is silently empty. #### Results, export and sharing - [Why a NetSuite saved search shows only 500 rows in the UI](https://mokuhub.com/answers/saved-search/saved-search-ui-shows-only-500-rows): The results page renders a fixed 500-row window and never says so. The size URL parameter is ignored, there is no truncation warning and no pagination control, and the correct Total sits at the bottom of a page showing a fraction of it. The CSV export from the same page is complete and matched that Total exactly. - [Why the saved search CSV Total row is not a number](https://mokuhub.com/answers/saved-search/saved-search-csv-total-row-not-a-number): The Total row formats that column differently from the rows above it, adding a thousands separator and a trailing .0, which forces CSV quoting. A parser gets integers for the body and a string for the total, so a cast returns NaN or a value silently truncated at the separator, on the total row only, with no warning. - [Duplicate column headers in a NetSuite saved search CSV](https://mokuhub.com/answers/saved-search/saved-search-csv-duplicate-column-headers): NetSuite writes the column label straight into the CSV header with no disambiguating suffix, so selecting the same field twice gives you the same header twice. The fix is custom column labels: they are honoured exactly as typed, in both detail and summary exports. - [Make a NetSuite saved search public: Public vs Audience](https://mokuhub.com/answers/saved-search/saved-search-make-search-public): Tick the checkbox labelled Public on the saved search form. Internal roles and External roles control who can see it, Allow Audience to Edit controls whether they can change it, and Available for Publishing on Website is a different feature about website publication rather than internal sharing. Run Unrestricted sits next to them and decides whose permissions the search runs with. ## Key Pages - [Pricing](https://mokuhub.com/pricing): Plans for MokuField and MokuBot - [FAQ](https://mokuhub.com/faq): Frequently asked questions covering MokuBot and MokuField - [Contact](https://mokuhub.com/contact): Sales, support, and integration inquiries - [MokuBot on Chrome Web Store](https://chromewebstore.google.com/detail/mokubot-ai-agent-for-nets/mhgajdlpjgndlgilcaoifhelkfjmkhio) - [Privacy Policy](https://mokuhub.com/privacy-policy) - [Refund Policy](https://mokuhub.com/refund-policy) ## Documentation - [MokuField FAQ](https://mokuhub.com/faq.md): AI-optimized FAQ covering setup, integrations, mobile, and data export - [MokuBot vs NetSuite AI Connector](https://mokuhub.com/mokubot-vs-netsuite-ai-connector.pdf): Feature-by-feature comparison (PDF) ## FAQ Quick Reference MokuBot: - What is MokuBot? AI agent that lives inside NetSuite as a Chrome side panel and executes tasks from plain-English instructions using the active session. - How is it different from other AI tools? Most AI tools generate code or suggestions you implement yourself. MokuBot executes tasks autonomously by chaining tool calls. - Who is it for? Business Analysts (avoiding SuiteQL), Admins (managing configs), Developers (debugging scripts), Finance/Ops (building reports). - Does it write SuiteQL? Yes, fetches field names, writes optimized queries, executes, and displays results. - Does it create Saved Searches? Yes, end-to-end including saving to the NetSuite account. - Does it help with SuiteScript? Yes, generates code, uploads to File Cabinet, creates script record, deploys. - Can it debug errors? Yes, searches execution logs and analyzes source code to diagnose failures. - Is it secure? Uses the existing browser session (no separate OAuth/REST), Read-Only mode by default, write tools disabled by default. - Bundle required? No, Chrome extension only. - Free trial? Yes, 30 days, no credit card. MokuField: - Offline support? Yes, native iOS/Android apps work offline; data syncs when reconnected. - Custom forms and checklists? Yes, configurable per work order type. - Mobile apps? Yes, iOS and Android. - QuickBooks integration? Yes, QuickBooks Online is fully implemented. - Xero or Zoho Books? On the roadmap; QBO is live today. - Google Workspace? Not on the current roadmap; we respond to customer requests. - GPS tracking? Built-in via the mobile app (Google Maps); telematics available as custom integration. - Where is data stored? AWS, encrypted at rest and in transit, per-organization database isolation. - Data export? CSV/JSON/PDF on demand, no lock-in, no fees. - Multi-country? Yes, supported. - Max technicians? No hard cap, pricing scales with seats. - Support? Included for all plans. - Free trial? Yes. - Implementation time? Typical setup measured in days, not months.