What's New in Frappe
Every notable change across the Frappe ecosystem.
Yesterday — Tuesday, July 28
Book Expenses Added To Stock GL entries
Backport to v16 of the develop-branch GL composer for Expenses Added To Stock, enabling proper accounting of costs like freight or insurance bundled into finished goods.
Incorrect creation time at cancellation
Creation time was being incorrectly set when cancelling an entry with the same posting datetime, causing data issues.
Align Opportunity status checks with Quotation statuses
Opportunity status checks looked for the obsolete Quotation `Closed` status instead of `Cancelled` and `Expired`, and didn't recognize `Partially Ordered` quotations as ordered. Now treats the right statuses and marks Opportunities Converted as soon as a Sales Order is created against part of a Quotation.
Pool batch slot values on every run, not only when negative
Batch slots' value differences were only spread across age slots when consumption had already driven one negative, leaving skewed splits (e.g., 10 units at 0 and 10 at 10 showing 0 and 100 instead of 50 each). Now pools slot values on every run.
Flaky test in exchange rate revaluation
Exchange rate revaluation test was non-deterministic due to time-based ordering; stabilized by using fixed timestamps.
Release raw-material reservation when closing a subcontracting order
Bin.update_reserved_qty_for_sub_contracting() skipped closed Purchase Orders but not closed Subcontracting Orders, so closing a partially-received SCO kept the raw-material reservation for the unreceived qty. Applied the same status != "Closed" filter to both paths.
Value batched packed-item returns from the original bundle
Return Delivery Notes / Sales Invoices built via the use_serial_batch_fields path had incorrect bundle valuations because the return bundle's voucher_detail_no stayed the Packed Item instead of remapping to the parent DN/SI Item. Valuation lookup now resolves via the parent_detail_docname when the direct lookup fails.
Keep manufactured item rate at zero when inputs are free
When a finished item was manufactured from raw materials consumed at zero valuation, _set_incoming_item_rate treated zero cost as missing and fell back to the item's own valuation rate, inflating the finished good's value on every production run.
Add support for async options in dropdown menu
Dropdown menu now supports asynchronously-loaded options.
Better read-only and impersonation banners
Improved visual design of read-only and impersonation banners on forms.
Consolidate view switching to single dropdown
List, kanban, and report views now use a single dropdown menu to select layout, available on mobile too (previously had separate dropdowns).
Add order to desktop menu item
Desktop menu items can now have a specified order so logout can be positioned last.
Constrain read-only Text Editor field height with scroll
Read-only Text Editor fields now scroll instead of expanding infinitely.
Don't show private custom workspaces on the dock
Private custom workspaces were showing on the app dock even though the new information architecture requires workspaces to be scoped under an app.
Grid row selection on touch
Touch-based row selection wasn't working on grids due to event handling differences between touch and click.
Stop build_index looping forever on an unindexable batch
SQLiteSearch.build_index advanced its pagination cursor only inside `if documents:`, so batches where all documents were rejected (no text-field content) never advanced the cursor and looped forever. Forward-port of #41249 from version-16-hotfix.
Get_locale_value() crashes when no language is set
get_locale_value() assigned value only when lang was set but always returned it, raising UnboundLocalError when no language was configured (e.g., bench console on sites that never set a language). frappe.sendmail() failed rendering emails because date-format lookup crashed.
Drop client-side grant-all rights for Administrator
Reverts the blanket grant of all rights to Administrator at all permlevels on every doctype. Administrator was getting submit/cancel/amend buttons on non-submittable doctypes like Bin, and malformed update_child API requests.
Validate HTTP method for document calls
Backport enforcing whitelisted methods' declared methods= on document-method routes (/api/v2/document/*/method/* and POST /api/resource/*/method routes), which was previously unenforced despite being enforced on /api/method/* and run_doc_method.
Resolve AttributeError in update_job_applicant_status exception handling
Fixed variable shadowing bug where the Document instance was overriding the string parameter job_applicant, and replaced job_applicant.log_error() with frappe.log_error() in the except block to handle empty/invalid strings.
Format earned leave schedule dates
Earned Leave Schedule dates in Leave Allocation now respect the System Settings date format instead of showing raw ISO dates.
First Ticket tag and tag charts on the dashboard
A "First Ticket" tag is now applied automatically to each requester's first ticket, plus two tag charts on the dashboard to surface patterns.
Convert link_filters to dict before search_link
Setting **Link Filters** on a Link-to-User field via Customize Form broke the New Ticket page; user_query expected a dict but received a list of lists from Customize Form.
Keep the last recent activity row out of the bottom fade
The last row in **My Recent Activity** was always rendered faded because the bottom scroll fade was pinned to the card with no notion of scroll position. Added padding to push content above the fade.
Drop the razorpay dependency
LMS pinned razorpay~=1.4.1 while payments (a required app) pins razorpay~=2.0.0 — disjoint ranges that bench only resolves by luck. Nothing in LMS imports the SDK; payments owns it. Dropped the dependency to stop chasing version ranges.
Count a coupon redemption once per payment that was actually paid
Coupon redemptions were counted wrong (two concurrent redemptions both read the same count, one was lost), and gateway retries picked the wrong Integration Request. Fixed race condition with atomic update and used the correct request for retry.
Resolve private lesson media whose file_url contains _ or %
Uploaded lesson PDFs failed to load (403) for enrolled students when the file name had an underscore or %. The access check escaped _/% in a way the query builder double-escaped, so it matched nothing and denied access. Used bound query to fix escaping.
Seed Google Meet account form on mount
GoogleMeetSettings edit swapped list and form with v-if/v-else, mounting the form fresh on every open with accountID already set. The watcher had no `immediate` option so it never fired; saving also called rename_doc with an empty new_name.
Broken access control
Added server-side authorization checks to get_profile_details (filters privileged roles from students), track_video_watch_duration (requires lesson access), and submit_quiz (requires quiz access).
Stop razorpay from breaking
Razorpay <2 imports pkg_resources at module level; setuptools 82 dropped it. LMS imported razorpay at module level in a hook that runs on every session, so any bench with setuptools ≥82 returned HTTP 500 for all requests including login and Desk. Bumped razorpay past the broken range and moved the import inside the get_client() call.
Validate contact email/mobile and rework the primary dropdown
Draft states caused failures in contact email/mobile autosave. Consolidated duplicated contact panel logic from Contact.vue and MobileContact.vue into a shared util and reworked the primary dropdown.
Replace centralized host mesh controller with ANCP (Atlas network control protocol)
Introduces `atlas-networkd` daemon using a distributed network protocol (ANCP) instead of a centralized controller for private networking.
Sleepy VMs: idle VMs sleep to free RAM and wake on the first inbound TCP connection
Puts an idle VM to sleep and resumes it on demand via host reboot recovery or — transparently — the first inbound TCP connection. Sleeping VMs keep their disk but release RAM to the host. Opt-in per VM via `sleep_on_idle`.
Surface sheets in Drive as content files
Sheets are now a Drive content-app; each new Sheet creates a backing Drive File, so sheets show up in — and open from — Drive just like Writer and Slides.
TDS filing integration
Added TDS (Tax Deducted at Source) filing integration.
Access slot props, pass dynamic slots, add components from context menu
Components inside a slot can now access slot scope/props, dynamic slots can be passed, and components can be added from the context menu.
Card-per-question layout for the public form
Splits the single form card into one quiet card per question on the public respondent form, following the Google Forms pattern with hairline borders, 10px radius, generous padding.
Mobile PWA navigation shell and touch UX
Mobile-only revamp of Mail's chrome with a bottom tab bar (Mail, Screener, Search, Profile) and Compose FAB; desktop unchanged. Tab and FAB step aside in thread view, selection mode, and search.
Admin password reset
Added admin password reset and sessions management UI.
Match Tally group names case- and whitespace-insensitively
Customer/Supplier classification was keyed on exact, case-sensitive match of Tally group names (e.g., `SUNDRY DEBTORS` vs `Sundry Debtors`), so mismatched groups silently imported parties as plain ledger Accounts instead.
Show all day event as all day event
All day events now display as "all day" instead of "12am - 12am".
Run invite account creation as Administrator
The invite/request-key endpoint runs as Guest but the setup it triggers (archive mailbox / automation sieve) resolved ownership from the session user, throwing "account does not belong to Guest" and rolling back, then every retry failed with primaryKeyViolation.
Use semantic tokens instead of tailwind text classes
Replaced old text colors with semantic text-ink tokens in the button component to fix color contrast and accessibility issues.
Preserve caller aria-label; Checkbox: emit model updates once
Button was silently discarding caller-provided aria-label and overwriting it, and Checkbox was emitting model updates multiple times per change.
Use updated loan limit for disbursement
A secured term Loan could be submitted without a Maximum Loan Amount; adding it after submission didn't persist correctly and Loan Disbursement calculated available limit as zero, failing disbursement.
Saturday, July 25
Block sales invoice submit when customer overdue exceeds threshold
Backport of credit limit enforcement: blocks Sales Invoice submit when a customer's overdue amount exceeds configured limit unless the user holds a bypass role.
Map pick list customer to delivery note when no sales order
fix: map pick list customer to delivery note when no sales order
Enable the 'Include Zero Stock Items' filter by default to show zero-stock items in the Stock Balance report
fix: enable the 'Include Zero Stock Items' filter by default to show zero-stock items in the Stock Balance report
Map MT940 per-transaction reference from :61: customer_reference
MT940 import was using the statement-level reference for all rows (making them indistinguishable) instead of the per-transaction reference.
Respect user permissions in party dashboard company list
Party dashboards were bypassing user permissions and iterating over all companies, exposing restricted data on forms.
Ignore permission while deleting user permission
fix: Ignore permission while deleting user permission
Silent autosave status and lighter builder chrome
Print builder autosave is now silent when saved, shows brief "Saving…" only during requests, and sticky red "Save failed" on error; drops "Reset Changes" and one-item section headers.
Open builder preview in a modal instead of a dock
Print preview now opens as a centered modal over the builder instead of a docked rail; gives preview full width and matches on-demand UX.
Add incident time and confirm noisy neighbours
Investigation now accepts optional `incident_time` for a centered 12-hour window (instead of trailing 24 hours), and confirms noisy neighbor detection.
Explain what makes a frappe version range invalid
Error message for invalid version ranges didn't name the range or explain the cause; now clarifies what makes a range invalid.
Set frappe requirement to >=15.0.0,<17.0.0
Prerelease version bounds were failing validation; corrected to use stable semver ranges.
Reload bench apps page on deploy update
fix(ui): Reload bench apps page on deploy update
Remove conflict markers from frappe version requirement
Backport merge left unresolved conflict markers in `pyproject.toml`, breaking TOML parsing and making bench unable to read the dependency.
Enforce app-version compatibility on deploy
App compatibility was validated on every save, causing deadlock when a release group had multiple incompatible apps; moved check to deploy time.
Fix branch-change tests broken
Tests were hitting the GitHub API and failing; mocked the `frappe/__init__.py` lookup so tests stay offline.
Google Sheets keyboard shortcuts + fix whole-line select anchor
Adds Shift+Space / Ctrl+Space / Ctrl+Shift+Space for row / column / whole-sheet select, Ctrl+Alt+=/- for insert/delete, and Ctrl+Shift+1…5 for format shortcuts; fixes Shift+Space anchor jumping.
Homepage list view — header sort, toolbar search, full-width scroll
Sheets homepage list now sorts from column headers (click to sort, click again to flip), toolbar search, and full-width scrolling; replaces separate "Sort by" dropdown.
Upgrade to frappe-ui v1
Upgraded Frappe Wiki to frappe-ui v1 (beta.25), migrated v1 component APIs, rebuilt editor chrome on frappe-ui atoms, and bumped tiptap to v3.
Integrated Code Editor [Experimental]
Built with Monaco editor and frappe-ui; allows editing code directly in Pilot.
Align CI and tests
CI and test base classes were misaligned with the version-2-beta branch; added correct Frappe/ERPNext versions and changed test cases to use FrappeTestCase.
Hide comment action if we are creating a comment
fix(writer): hide comment action if we are creating a comment
Update collaboration avatars in real time
Document loader wasn't shown on navbar due to missing reactivity; added `useCollaborationUsers` ref to track awareness users.
Include formula-cell values in selection Sum/Avg
Selection stats were miscounting formulas by reading raw cell content instead of computed values.
Handle errors when offline or server unreachable
fix: handle errors when offline or server unreachable
Pass is_private as false correctly
fix(file): pass is_private as false correctly
Paste without a priming click + refresh formula bar on paste
Paste did nothing unless the grid was focused, and the formula bar showed stale values right after a paste operation.
Remove invalid doc.guardian reference breaking guardian search functionality
Guardian search was filtering with a nonexistent field, blocking users from linking Guardians to Students via the Relations tab.
Preserve repayment_type before building GL entries on repost
Loan Repayment Repost was rebuilding GL entries with the wrong account and voucher_subtype when `before_validate` hooks changed the repayment type.
Friday, July 24
Warn when a draft linked document already exists
When creating a follow-up document (e.g. Delivery Note from Sales Order), confirmation dialog warns if a draft linked to the same source already exists with clickable links.
Make Shipping Rule Cost Center optional with company default fallback
Cost Center on Shipping Rule is now optional; falls back to company default, avoiding P&L account validation errors for income accounts.
Proforma Invoice against Sales Order
New submittable, non-accounting `Proforma Invoice` doctype (posts no GL/stock) for advance payments, created only from Sales Order with per-line Quantity/Amount basis.
Log exception instead of swallowing in notify_errors
Error logging now reports exceptions instead of silently swallowing them.
Restore Save button on reverse journal entry
Save button was missing from reverse journal entry form.
Incorrect creation time at the time cancelling an entry
Document creation time was incorrectly set when cancelling entries with same posting datetime.
Drop translation marking from default warehouse names
Warehouse names were marked for translation at creation but never actually display translated (docname carries untranslated company abbr); removed marking.
Respect selected BOM when creating work order for variant item
Non-default BOM selection was silently reset to the variant's default BOM; now only substitutes for template BOMs.
Production Plan raw material qty calculation and bin reservation
When same raw material appears in multiple Production Plan rows, safety stock and MOQ were added per-row instead of once; now reserves it as a floor.
Map pick list customer to delivery note when no sales order
Creating a Delivery Note from a Pick List without a linked Sales Order left the Customer blank; now falls back to the Pick List's own Customer.
Guard against missing is_your_company_address custom field on Address
Controller reads `is_your_company_address` as a bare attribute, crashing with AttributeError if the optional custom field is missing (e.g. after interrupted migration).
Rebalance batch slot values at the pooled rate when driven negative
Batch valuation showed small negative bucket values when consumption drove a slot negative; now spreads batch pool value across slots proportional to qty.
Create default warehouses with untranslated names
Warehouse names were translated at creation, breaking opening-stock fallback lookups from sessions in different languages.
Do not translate default record lookup keys
Company creation was looking up Department root via `_(\"All Departments\")`, missing it on non-English sites and corrupting the tree.
Do not translate root Item Group lookup key
Non-English setups stored the root under a translated name, making new groups save with blank parent and become uneditable second roots; now uses `get_root_of`.
Accept dict target_doc in mapper endpoints
With native JSON request bodies, `map_docs` forwards `target_doc` as a dict, breaking all "Get Items From" buttons; now accepts dict/str/Document.
TypeError in get_batches_by_oldest for mixed batch expiry
Fixes crash when a warehouse has both dated and non-expiring batches; expiry_date is nullable but sort was comparing directly.
Full screen toggle for the builder preview
Print builder preview can now toggle full-screen; same iframe grows to viewport with Esc or shrink button to restore dock.
Update private workspaces on user rename
When a user's email changes, their private Workspace documents are now renamed and updated.
Re-hash vue-style bundle filenames after inlining CSS
CSS-only edits now mint new bundle URLs instead of shipping under browser-cached ones.
Close the bordered child-table bottom and drop the doubled header line
Fixed child-table styling: bordered tables now close cleanly without doubled header line.
Missing doctype name in breadcrumbs
Doctype name was missing from breadcrumb navigation.
Notifications with the dock
Notification panel now shows up correctly with the dock.
Remove hover effect from column/table resize handle
Column resize handle no longer darkens on hover, reducing visual noise.
Pass parent doctype when fetching child table link values
Fetching a Link field from a child-table row was failing permission check because parent doctype wasn't passed to `get_value`.
Unbuffered sync from mariadb to duckdb
Batches rows into Apache Arrow columnar format for zero-copy DuckDB ingestion.
Stable memory consumption while syncing
Large GL syncs (1.5M rows) to DuckDB were accumulating memory; now drops consumed objects.
Get_list_context called twice when rendering a portal list
Portal list pages were calling the doctype's `get_list_context` hook twice, duplicating queries and sidebar work.
Use a re-entry flag instead of freezing during mapped doc guard runs
Freeze overlay at z-index 2000 was covering confirmation dialogs from guards (at z-index 1140), blocking user interaction; replaced with re-entry flag.
Replace swap metrics with OOM for server health check
Server health monitoring now tracks OOM instead of swap metrics.
Raven channel name for alerting server health
Channel name now follows slug convention: "frappe-cloud-server-alerts".
Navbar refresh, fix blank Breadcrumbs page, and speed up dev cold load
Docs site polish: full-width navbar, sidebar styling, centered search, anchor link fixes, IntersectionObserver for active headings.
Actually unify sites and assets
Unified list view for sites and VMs removes confusion about where site creation happens (Pilot, not Central).
Responsive sidebar
Mobile-responsive sidebar using frappe-ui desktop/mobile shell components and bottom-sheet for mobile.
Meet links on existing events, richer meet row
Meet links can now be added to existing events via new `create_meet_link` endpoint; event updates now preserve existing links.
Meet stats for nerds
Developer stats panel for Meet showing detailed metrics.
Store Entry browser to browse Tantivy search indexes
Read-only Store Entry browser now extends to search indexes alongside Data/Blob stores using schema-agnostic `SearchIndexBrowser`.
Sheets homepage filters, recency groups, and server-side pagination
Sheets homepage upgraded: ownership tabs (All/My/Shared), sort control (Modified/Name/Owner), recency groups (Today/Previous Days/Earlier), server-side pagination.
Auto-link URLs and link preview hover card
URLs (https/www/common TLDs) auto-detect and auto-link in cells; hover card previews with quick actions.
Multi-line cells via Cmd+Enter with auto-growing rows
Sheets now support Google-Sheets-style multi-line cells; Cmd/Ctrl/Alt+Enter inserts newlines, rows auto-grow to fit.
Server overview metrics
Pilot integration for server overview metrics on the Central dashboard.
Add Credentials settings tab to manage JMAP connection
New Credentials tab under Mail Settings lets users view/update JMAP connection fields (Username, App Password, Server URL); Password is never prefilled.
LLM integration
New LLM integration in settings with task debugging: setup in settings, explain/query errors with full context, stream output via SSE.
Make a bench fully operable without root after install
Privileged operations (nginx, certbot, supervisor, modsecurity) now run once in root installer pass or through scoped sudoers; bench user no longer needs passwordless sudo.
Versioned releases and in-app self-update
Moved from git-tracking to versioned releases with in-app updates; GitHub releases include prebuilt frontend, `install.sh` pulls latest, Settings shows version with check-for-updates.
Render SVG at zoomed size
Server map SVG now renders at proper zoomed size.
Active highlight for sidebar item
Sidebar active state highlighting now works correctly.
Misc sidebar issues
Sidebar UI polish: fixed switch label colors and migration button spacing.
Screener polish, Screener settings tab, iOS install banner
Mail screener UI polish: full-width explainer slab, Screener settings tab, iOS install banner as fixed bottom sheet.
Enable settings shortcuts
Settings shortcut (Meta+Shift+,) now works across all apps.
Ignore paused producers in stall detection
Meet stall detection was flagging paused video/audio producers as stalled.
Anchor release tarball excludes to repo root
`tar --exclude` was matching patterns globally (e.g. `--exclude=benches` also matched `admin/backend/api/v1/benches/`), shipping incomplete tarballs.
Install Redis system-wide from the installer
Every bench runs its own Redis, but the installer never installed it system-wide; `RedisManager.install()` tried to sudo-install at bench-init, failing without passwordless sudo.
Enable lingering in the root pass, verify it in the bench-user pass
Follow-up fix: moved lingering enable to root installer pass (where it belongs) and added verification in bench-user pass.
Enable systemd lingering for the bench user at install time
Bench services run as systemd user units, but lingering was only enabled after MariaDB provisioning (the first `systemctl --user` caller), causing install to crash.
Skip frontend Node deps on released installs
Released installs were pulling `node_modules` for the admin frontend despite never compiling it; now gates on `is_dev_install`.
Serve bundled admin UI on released installs instead of rebuilding
Released installs were rebuilding the admin UI on every `bench init`, even though the tarball ships it prebuilt; now decides by version flag.
Show real sheet owner in Share dialog instead of current viewer
Shared sheet's Share dialog mislabeled the real owner as yourself; `get_sheet` never returned `owner` field.
Re-baseline undo history after load so insert-column undo doesn't blank the sheet
Inserting a column and pressing Undo blanked the grid; history baseline was initialized before sheet data loaded, capturing empty state.
Keep renamed sheet tab in place instead of jumping to the end
Renaming a sheet tab moved it to the last position; now preserves position by restructuring the sheets object carefully.
Import context menu in grid view
Missing context-menu import in Drive grid view prevented it from opening.
Thursday, July 23
Made territory field multi select
Territory field on accounts receivable reports now accepts multiple selections.
Get reserved batch qty precision from settings (v16)
V16 backport of reserved batch qty precision fix.
Get reserved batch qty precision from settings
Reserved batch comparison now respects field precision instead of hardcoding 6 decimal places.
Seed cancelled voucher replay from before its posting datetime (v15)
Cancelled voucher replay now uses the correct previous balance, preventing double-counting when SLEs share the same posting datetime.
Disable Werkzeug debugger
Development server no longer exposes Werkzeug interactive debugger.
Remove s3/gh code assets fetching logic
Removed unused S3/GitHub code asset fetching that was causing 1-2s build delay.
Add guard hooks to open_mapped_doc
Adds sanctioned extension point with `add_mapped_doc_guard()` and `should_open_mapped_doc()` to intercept before opening mapped documents.
Duplicate title in list view settings dialog
Removed duplicate title in list view settings dialog.
Detach duration picker to avoid css issue
Duration picker now renders detached to avoid CSS stacking context issues.
Preview in print format builder for cancelled documents
When print format settings disable printing cancelled/draft documents, those documents no longer appear in the preview filter.
Handle orphan doctypes doctypes
Orphaned doctypes no longer cause errors during sync operations.
Store OAuth state server-side instead
Google OAuth hardening with server-side state storage instead of JSON encoding.
Display ticket priority as icon and level
Replaces arbitrary `integer_value` on HD Ticket Priority with purposeful `level` field (Urgent/High/Medium/Low) and renders as icon + name.
Rtl support
RTL support backport with physical-to-logical Tailwind utilities and directional icon rotations.
Recent Activity card on Home dashboard
Agents now see a Recent Activity card on home showing recently-acted tickets with action types (Replied, Commented, etc) and clickable rows.
Load real italic faces through the ital axis
Google Fonts loader now requests italic axis alongside weight, so italic text renders with real italic faces instead of browser-synthesised slant.
Align border control with spacing split-mode inputs
Border control now supports split-mode inputs (top/right/bottom/left) matching spacing and border radius layout.
Invite users to Builder
Site members can now be invited to Builder by email without going through Desk; invitees get Website Manager role on accepting.
Default screening on only for personal accounts
Email screening now defaults to off; only personal accounts get it on by default, shared/delegated stay off.
Enable hot reload by default on dev benches
Dev benches now hot-reload both Python and JavaScript by default without explicit bench.toml settings.
Slicers — floating value-filter controls
Draggable in-sheet panels that filter by column values via checklist, reusing the existing sortFilter engine.
Recoverable trash for deleted sheets
Soft-deletes sheets to trash instead of hard-deleting; 30-day retention with recovery like Google Drive/Figma.
Complete llm hosting
Completes LLM hosting service with console activation, API key issuance, and per-site enable via Pilot.
Keep forwarded emails in the same thread
New per-account setting to add `In-Reply-To` headers to forwarded emails so they thread with originals.
Add basic DB analyzer support
Basic database analyzer support with lock wait timeouts, active connections, and process list tasks.
Databse Insights
Adds database insights with lock wait timeouts, active connection counts, binlog purge information, and process list.
Name the bench in the wizard's finish hints
Setup wizard now names the bench in finish commands when multiple benches exist.
Use alpha gray for focus and open item backgrounds
Menu background no longer shifts when a submenu opens; focused and open states now both use alpha tokens.
Properties panel stealing focus from text editor
Properties panel writes no longer steal focus; color picker can be dragged, text highlighting persists, and arrow keys work in numeric inputs.
Stack avatar group to the right
Avatar group now stacks to the right for better layout.
Allow moving a block inside a slot and deleting a slot from layers panel
Layers panel now supports moving blocks into slots and deleting slots, helpful when the UI drop target is too small.
Fix notifications empty state alignment
Notifications empty state now aligns with tab buttons via responsive left margins.
Preserve tree expand/collapse state on column freeze
Tree expansion state is now retained when freezing/unfreezing columns.
Punctuation jumping when editing text elements
Enabled contextual alternates on ProseMirror editor and fixed text run shaping to prevent punctuation from jumping vertically during editing.
Mention dropdown stays dead after typing a name with no match
Mention suggestions dropdown now re-opens after typing a non-matching query and deleting back to a matching prefix; was failing due to conditional root element rendering detaching popover content.
Wednesday, July 22
Ensure payments app installed on the site in payment_app_import_guard
Prevents errors when payment operations run before the payments app is installed.
Sync process loss percentage when FG qty changes
Manufacturing rework now re-derives stale process loss percentage when finished goods qty changes.
Show transaction currency symbol in Payment Request schedule dialog and reference table
Multi-currency Payment Requests were showing company currency symbol instead of transaction currency.
Read serial and batch flags from Item in Stock Balance's SLE query
Stock Balance query was missing `has_batch_no` and reading `has_serial_no` from wrong column, breaking batch/serial consumption matching.
Rescale stock ageing FIFO slot values on stock reconciliation
Stock Ageing showed negative bucket values when revaluing existing stock; each slot's value is now re-derived as qty × valuation_rate.
QUERY HTTP method (RFC 10008)
Frappe API now supports RFC 10008 QUERY HTTP method for GET-like transaction semantics with POST-like body handling.
Store builder snippets in a DocType
Print Format snippets moved from localStorage to a DocType, making them exportable and shareable across sites/devices.
Web Form: add request-key access for one-time links
Web forms can now be shared via one-time private links with pre-filled context, enabling secure workflows for non-users.
Add print option in form menu on mobile
Print action now appears in form menu on mobile devices for easier access.
Collapse interaction for dock
Workspace dock collapse interaction is now working.
Multiple changes in duckdb sync
DuckDB sync now uses db_port from frappe.conf, shows filenames, ignores links on cancel, and doesn't set primary key.
Give datatable a definite height on mobile
Query reports on mobile now render with proper datatable height so HyperList virtual scrolling works.
Add ignore_permission param to remove_user_permission util
User permission removal now accepts ignore_permission parameter.
Rename workspace missing icon in db
Workspace icon naming is corrected in database.
Make the create new button subtle
Create new button styling is now more subtle.
Make shell selection module first
Sidebar selection is now module-based instead of role-based.
Check image before trying to load in print
Print formats now skip empty image attachments instead of attempting to load them.
Restore compact email button size
Email button sizing regression from spacing redesign is reverted while keeping dark colors.
Don't flag builder blocks as missing fields in the outline
Builder-only fieldtypes (Repeater, Spacer, Divider) no longer wrongly report as missing fields.
Respect select field ordering
System console output columns are no longer forced to sorted order.
Show a session expired message and redirect to login instead of "Method Not Allowed"
Expired sessions now show a clear message and redirect to login instead of cryptic "Method Not Allowed" errors.
List view filter on child table link field with ignore user permissions
Filtering by child-table Link fields with Ignore User Permissions no longer fails validation.
Dock the preview, move print settings to a dialog, section radius
Print Format Builder preview now docks beside the canvas with live refresh and improved print settings UI.
Fix pytz to filter out deprecated timezones
Timezone API now excludes deprecated entries like Asia/Calcutta using pytz instead of zoneinfo.
Broken spacing in email templates
Redesigned email containers with proper card layout, padding, and typography.
Persist allow_bulk_edit for custom table fields
Allow Bulk Edit checkbox was auto-unchecking on save for custom fields; added missing column to Custom Field doctype.
Empty state text for list views
Fixed button styling and simplified empty state messaging in list views.
Connected app: add permission check & sanitize redirects
Prevents redirect injection and unauthorized app flows.
Add permission checks to prepared_report & query_report
Hardens report access by adding permission validation to prevent unauthorized access.
Filter system users in department approver tables
Department approver fields now filter to show only System Users, preventing Website Users from being selected.
Skip expire_allocation for already-cancelled Leave Allocations
Leave expiry no longer processes cancelled allocations.
Exclude cancelled Vehicle Log records from service expense report
Service expense totals no longer inflate from cancelled vehicle logs.
Exclude cancelled Attendance records from employee timeline
Employee dashboard timeline now filters out cancelled attendance entries.
Exclude disabled users from approver list
Disabled users no longer appear in leave, expense, and shift approval searches.
Allow manual product sync regardless of bidirectional toggle
Manual product sync is now always available independent of bidirectional setting.
Lead/deal report 500s when a child-table column is selected
Permission conditions now properly qualify column names to avoid ambiguity when child tables join.
Add playbook to update ProxySQL on proxies
Playbook added to upgrade ProxySQL from 2.3.2 to 3.0.9 across all proxies with atomic backup and rollback.
Allow more actions on inactive sites
Inactive sites now support reinstall, restore, migrate, and update operations; update_without_backup now matches schedule_update allowed states.
Ignore failed-over proxies in wildcard skip check
Wildcard DNS check no longer counts failed-over proxies as active, preventing per-site record misplacement.
Make partner lead page a lil responsive
Partner lead page now renders functional layouts on mobile.
Improve app-mismatch error when moving a site
App mismatch errors now bold offending app names and link to documentation.
Branch change for framework
Framework branch changes are now allowed if major version matches the release group.
Determine post-login redirect route entirely in backend
Login flow now determines redirect route server-side instead of trusting frontend logic.
Send already-logged-in product signup through quickstart
Logged-in users completing product signup are now routed through quickstart flow.
Add read-only SQL query command
CLI tool now includes read-only SQL query command with interactive table results and piped/JSON output support.
Slugify server subdomains
Server subdomains are now automatically slugified and polished UI added for new server page.
Add missing indexes
Performance indexes added for Invoice, Payment Attempt, Usage Rollup, Subscription, and Credit Ledger Entry queries.
Unified assets list view
Servers and sites now unified in single console map + list view, allowing single-site users to find their site and multi-site owners to see everything at once.
Rollback imports on failure
JMAP importers (Mail, Calendar, Exchange) now stage imports atomically; failure at any point rolls back the entire batch.
Custom event invitation emails with RSVP links
Calendar now sends custom invitation emails with HTTP RSVP links, with configurable Mail Settings toggle.
Add Suite User and Suite Admin roles, simplify Mail/Calendar permissions
New Suite User and Suite Admin roles replace blanket All role with owner-scoped, role-based permissions for Mail and Calendar.
Draggable corner radius handle
Slides designer now offers draggable corner handles for round rectangles, images, and videos.
Redesign event modal
Calendar event creation modal redesigned with two-pane layout, grouped date/time card, participants rail, and human-readable repeat rules.
Google-Sheets formula UX — click-to-range, auto-close parens, range suggestion
Sheets formula editor now supports Google Sheets parity features: click-to-extend ranges, auto-closing parentheses, and range suggestions.
Writer-style share dialog redesign
Sheets share dialog now matches Frappe Writer/Drive style with unified typography and consistent design language.
Harden ingest: validation, dedup, capture rules, event catalog
Event ingestion validation hardened with dedup logic, capture rules, and event catalog.
Namespace gateway payment id by provider
Gateway payment IDs are now scoped by provider to prevent ID collisions across multiple gateways.
Add tsconfig for type stuff in admin dashboard
TypeScript configuration added for admin dashboard.
Implicitly allow dropping in a component that has a default slot + other slot fixes
Components with default slots can now wrap other components without explicit slot passing.
Forward sidebar-item slot to SidebarSection
Sidebar component now properly forwards slot when using sections API.
Fill unpinned column before creating a 2nd column
Meet video grid now fills a single column before wrapping to multiple columns.
Ask for device perms on demand in device settings
Frappe Meet now requests device permissions on-demand in settings instead of upfront.
Unify sidebar state and hide storage labels on collapsed
Sidebar state is now consistent across sections and labels hide when collapsed.
Stop the login layout from shadowing bare /mail
Bare `/mail` URL no longer shows empty account creation card for logged-in users.
Reset stalled receive connection
Frappe Meet connection stalls are now recovered.
Smooth, tight-fitting document title input
Sheets document title input no longer jitters on keystroke by removing width animation and using native input sizing.
Resolve event masters via baseEventId so fresh events can be edited
Freshly created calendar events can now be edited immediately by resolving masters via baseEventId instead of stale search index.
Allow site operations in production
Site operations now work in production by allowing passwordless sudo access to nginx.
Drop certbot quotes
Certbot configuration no longer includes unnecessary quote escaping.
Certfile test is root-only
TLS certificate tests now handle permission-denied gracefully in non-root runs.
SSL flag
Removing SSL ready flag no longer takes away HTTPS from other sites.
Sunday, July 19
Scope current serial nos to the selected batch in stock reconciliation
Serial numbers in stock reconciliation now scoped to selected batch instead of pulling from all batches in warehouse.
Live preview renders unsaved edits through the print pipeline
Live preview now renders unsaved edits via the print pipeline; canvas values from server's `get_formatted` kill preview↔print drift (address `
`, currency, links).
Custom permission types denied for Administrator on client
Restores evaluation of custom permission types for Administrator on client after merge conflict from backport.
Make builder preview pixel-match print output
Aligns print format builder preview styling with print output (light-theme lock, token values, gray palette).
Preserve numeric values across locale formats
Numeric filter values (e.g., 7.95) are preserved across locale-sensitive number formats instead of being truncated to integers.
Scope preview cleanup to generated files only
Prevents deletion of user-attached files when regenerating print format previews; saves new preview before cleaning stale ones.
Sweep all stale preview images on regenerate
Sweeps all pf-preview-* files before saving fresh preview, preventing orphaned files from interrupted renders.
Exclude Closed status ToDos from get_assigned_users
Syncs assigned users between single page and list page by excluding closed status todos.
Add thin Central proxy + JWKS-based bench↔Central auth
Central billing client and site-billing admin routes with JWKS authentication; usage meters composed server-side.
Add template renderer
Minimal Jinja2-like template renderer to simplify nginx config code and reduce f-string complexity.
Readable Flow Session transcript, Flow Run tweaks
Flow Session transcript renders as readable HTML instead of raw grid; Flow Run Input field read-only, Output trimmed on display.
Show failed tool calls in activity timeline
Surfaces a "Failed" badge on tool calls whose result is an error payload; message shown in dropdown.
Frappe Draw: unified-canvas polish (minimap coverage + library type filter)
Minimap now shows all content (block shapes, whiteboard objects, frames) on unified docs; "Drawing" type added to library filter.
Frappe Draw: in-frame editing (double-click a frame to edit it)
Double-click a mind-map or flowchart frame to enter it; the editor becomes that frame's single-type editor, with keyboard + contextual toolbar; "Back to canvas" bar returns to composed view.
Saturday, July 18
Automatically link portal users to their associated contact profiles for customers and suppliers
Portal users added to a Customer or Supplier now automatically link their existing Contact, making portal-visible records accessible.
Block sales invoice submit when customer overdue exceeds threshold
Opt-in per-customer Overdue Billing Threshold blocks Sales Invoice submit unless the user holds a configured bypass role.
Batch operation batch-size flag lookups to avoid n+1 query in work order
Batches operation batch-size lookups instead of querying per-row for every exploded BOM node.
Add fetch from in production plan material request child table
Adds fetch_from mapping for Production Plan Material Request items.
Strip account number when building account name in COA importer
Chart of Accounts importer strips leading numbers from account names.
Include on hold status in project filters and reports
On hold projects are now filtered correctly in Task/Timesheet selectors and appear in the Project Summary report.
Remove duplicate links from home and projects workspaces
Removes duplicate entries that appeared after workspace re-export in #56864, fixing doubled links in desk.
Fall back to the company in-transit warehouse
`set_transit_warehouse` now falls back to the company's default when the source warehouse has no in-transit default.
Replace column-literal work order filter with server-side query
Stock Entry's work_order link filter now uses a proper server-side query instead of a broken column-literal comparison that silently degraded.
Parallel reposting stalls between scheduler ticks
Enables continuous reposting by enqueueing the next batch immediately instead of stalling between 30-minute scheduler ticks, fixing throughput regression with large backlogs.
Validate buying price list on material request and update item rates on change
Defaults `buying_price_list` only when user has read permission, clears it on validate if not a buying list, and refreshes item rates when the list changes.
Force-delete repost data file during cleanup
Passes `force=True` when deleting attached Files during reposting cleanup so File deletion guard from frappe#40812 doesn't block the operation.
Add missing DF types for controller annotations
Type-annotates Geolocation, Signature, Icon, and Long Int fields.
Add N_ noop for translation extraction
`N_()` marks strings for gettext extraction without translating at call time.
Revoke old token after refreshing
Old token is now revoked after refresh.
Repeater row conditions and merged-column direction toggle
Print-format Repeater rows can now be conditionally shown with a Jinja expression; merged columns support LTR/RTL direction.
Composer — EmailComposer & CommentComposer
Two ready-to-use message composers: EmailComposer with headers/attachments/quoted replies, CommentComposer with @-mentions.
Virtualization
Windowed rendering for 2000+ row lists keeps only visible rows (+ buffer) in the DOM, preserving column widths and bulk selection across scroll/pagination/resize.
Translate description in info card when `show_description_on_click` is set
Info card descriptions are now translated when the toggle is set.
Allowlist print settings overrides to the doctype's print toggles
Caller-supplied print-preview overrides are now restricted to fields the doctype actually exposes.
Use normal exception instead of assert
Replaces assertions with proper exceptions for validation errors.
Fix!: Don't run frappe under optimize flag
Removes `-O` optimize flags which disable assertions without real benefit.
Column resizing in list view and child tables for RTL layouts
Column resizing now works correctly in right-to-left layouts.
Pass parent_doctype when fetching Has Role in Role form tabs
Passes `parent_doctype` to `frappe.db.get_list("Has Role", ...)` in Role form tabs, fixing "Insufficient Permission" errors for non-Administrators.
Sync comment cache on relink
Syncs comment cache on both old and new parents when relinking, fixing comment count mismatches on relayed Communications.
Blank columns when field is not in_list_view
Fetches configured columns that aren't in the default in_list_view set, waits for that before refresh so link titles don't lag.
Workspace save fails when adding a new chart or widget
Uses `frappe.parse_json()` in `save_new_widget` instead of re-parsing already-parsed `new_widgets`, fixing TypeError when saving workspace changes.
Schedule interview dialog on job applicant form
"Schedule Interview" dialog collects all details in one place with auto-populated interviewers from Interview Type.
Checkin button no longer defaults to IN while loading
Checkin button stays disabled until the last check-in loads instead of defaulting to IN.
Onboarding persona questionnaire
New admins see a one-time stepper collecting org name, team size, tooling, challenges, and goals; answers sent to telemetry.
Strip html comments from agent reply email content
Removes MSO conditional comments and other HTML comments from email replies before sending so markdown2 doesn't break them.
Make headers sticky in TicketsTab
Column headers in the Tickets Tab of Customer and Contact pages stay fixed when scrolling.
Prefill custom fields in lead to deal conversion form
Lead-to-deal conversion now pre-fills custom fields alongside default fields.
Sitemap seeding and extraction fixes
Crawl queue seeded from site sitemaps; also fixes extraction and follows nested sitemapindex files.
Capture feature adoption using pulse
Telemetry events track adoption of web forms, domain enrichment, and ERPNext integration features.
Refactor ERPNext product sync settings
Splits ERPNext product sync into two directions: Items always pull into CRM Products, pushing back is now opt-in via "Bidirectional Product Sync" toggle; adds Manual Sync button and sync logs.
Create product in CRM if opted out of bi-directional sync
Respects bidirectional product sync opt-out and doesn't redirect to ERPNext to create items.
Dim images by default in dark mode
Images without dark variants now apply subtle default dim (brightness 0.85, contrast 1.05) in dark mode.
Added per-corner control for spacing and border-radius
Split/uniform inputs for spacing and border-radius now allow per-corner control with label dragging.
Add quickstart page for new onboarders
New onboarders with ≤3 sites see a quickstart page after login.
Report public server pool health
Hourly job monitors public primary servers, fetches Prometheus metrics in bulk, chooses best server per cluster, and reports health via Raven.
Structured -F values (key:=json), fix GET --input
`-F key:=json` now parses JSON values; fixes `GET --input`.
Drop the "mutations run without confirmation" tip
Removes misleading guide text about mutations.
Let user know we are waiting for cache fill
User-facing message when waiting for cache fill.
Replace whole roles field instead of patching union discriminator
Stalwart account role assignment now patches the whole roles field instead of sub-paths.
Show plain-English intent for execute tool confirmations
Execute tool approval card now shows one-line `description` of intent as title with code below.
Canvas unification — Phase 3b: remove type selector, land on canvas
New diagrams are unified canvas by default; type selector removed and users land on blank editor immediately.
Canvas unification — Phase 4a: frame origin data model
Unified documents add `origin` {x,y} to mind maps and flowcharts; legacy single-type docs unaffected.
Canvas unification — Phase 4b: render mind map & flowchart as frames
Mind maps and flowcharts render as positioned frames on the unified canvas alongside block shapes and whiteboard ink.
Canvas unification — Phase 4d: Templates/Insert menu for frames
Insert menu adds starter mind maps or flowcharts to the unified canvas.
Canvas unification — Phase 4c: select & move frames
Mind map and flowchart frames are now first-class selectable/draggable objects on the unified canvas.
Frappe Draw: Writer-style diagram sharing (view/comment/edit) — backend
Diagram sharing built on Frappe core DocShare + custom "comment" permission type, no Drive dependency.
Frappe Draw: Share dialog UI wired to sharing backend (view/comment/edit)
Share dialog now wired to `draw.api.share.*`, adds comment-level access, and user-search endpoint for invites.
Frappe Draw: optional Frappe Drive integration (register diagram as a Drive file)
Diagrams can be registered as Frappe Drive native documents; soft-coupled with no Drive dependency.
Template library: 17 new template groups
Grows template catalog from 11 to 27 groups across Fashion, Portfolio, Technology, and Marketing.
Scope screening backfill to active, configured, fetching users
Screening patch now targets a precise set of active users with JMAP configured, avoiding redundant backfill.
Enable screening by default for new accounts
New JMAP Accounts start with screening enabled instead of requiring manual opt-in.
Collapse consecutive mails from the same sender in list view
3+ adjacent threads from one sender on one day render as a single expandable row, reducing list clutter (measured: 300 threads fold to 19 stacks).
Local email-address suggestions (Tantivy)
Local per-account full-text index powers email-address suggestions from cached messages and contacts without JMAP round-trip.
Protected cell ranges and sheet lock
Protected ranges and whole-sheet lock enforced across all write paths; ranges shift correctly on row/col insert/delete.
Lossless XLSX import/export
XLSX round-trip now preserves formulas, number formats, merges, and all sheets; replaces string-only bridge.
Threaded, resolvable cell comments
Cell comments turn into threaded discussions with resolve/reopen, @-mentions, and timestamps.
In-cell SPARKLINE mini-charts
`SPARKLINE(data_range, [type], [color])` formula renders line or column mini-charts in cells, inheriting recompute-on-change from the formula engine.
Editor layout, comments & read-only selection; drive dialog fixes
Unified editor scrolling, permanent comment gutter, restored text selection in read-only, and dialog fixes.
Flexible comment layout with chips and mobile support
Writer comments now use a symmetric grid with mobile-responsive chips and bottom sheet.
Fix move toast and move-dialog button state
Move operation now shows correct filename in toast and button state works when moving within same team.
Consistent empty states across pages
Unified empty-state rendering and copy across Attachments, Notifications, and other Drive pages.
Cancel error on loan security assignment when loan value is empty
Cancel no longer crashes when loan amount is None.
Keep execute description required so the model always supplies intent
Reverts default on execute tool description so the model always supplies intent text.
Make Flow installable on Frappe Cloud and v16
Adds `[tool.bench.frappe-dependencies]` and pins litellm to support Python 3.14 and Frappe v16.
Preserve custom keys in common_site_config.json
`write_common_site_config()` now merges over existing file instead of replacing it, preserving keys added via `bench set-config`.
Friday, July 17
Automatically link portal users to associated contact profiles for customers and suppliers
Automatically detects and links existing Contact records when portal users are added to Customers/Suppliers.
Book Expenses Added To Stock GL entries for stock vouchers
Books GL entries for expenses added to stock value movement, mirroring Purchase Expense pattern and making the feature configurable.
Map settings for DocTypes to show on settings dialog
Maps DocType settings to display in the DocType settings dialog General tab.
Consider min order qty in the purchase/transfer flow of production plan
Ensures minimum order quantity is respected when splitting purchase and transfer allocations in production planning.
Serialize postgres stock writes per (item, warehouse)
Adds transaction-scoped advisory locking for concurrent stock writes in postgres to prevent serialization failures and incorrect inventory.
New control "Attachment Gallery"
Adds standard form control for viewing, uploading, previewing, and deleting attachments with optional filtering.
Translate description in info card when show_description_on_click is set
Translates field descriptions in info cards when show_description_on_click is enabled.
Center the close button
Centers the close button in modal headers for better visual alignment.
Independent table style controls in print format builder
Decouples table style controls so Style controls only lines/stripes, Bordered controls column lines, and header controls header row independently.
Report why chromium failed to start instead of a blanket timeout
Reports actual Chromium startup failures instead of generic timeout message, improving CI debugging.
Honour print settings pdf generator for standard printing
Respects Print Settings > PDF Generator selection for standard printing instead of forcing Chromium, allowing wkhtmltopdf fallback.
Truncate MultiSelectList status text within the control box
Truncates long selected labels in MultiSelectList controls to fit within the component instead of overflowing.
Batch child-table fetch in data export
Batches child-table fetches during data export to improve performance and reduce database queries.
Render Markdown Editor standard filters as text search
Renders Markdown Editor standard filters as text search instead of complex filter UI.
Duplicate intro messages on first save of a new document
Fixes frm.set_intro() appending duplicate messages on first save by clearing previous message instead of always appending.
Guard against missing old_doc in validate_snapshot_reports
Adds guard to prevent AttributeError when System Settings is inserted fresh with no prior document to compare.
Various issues in sidebar
Addresses multiple sidebar UI issues including button centering and alignment.
Don't emit column fieldname as a CSS class
Prevents column fieldnames from being emitted as CSS classes, which could cause unintended styling or DOM pollution.
Do not translate empty string
Prevents translation of empty strings which was causing issues with gettext extraction.
Add a perm. chk for ref. document to update_reference method
Adds permission check for referenced documents to update_reference method, closing Ticket 72600.
Field inspector label and align/spacing conflict in print format builder
Shows field's real doctype label in inspector instead of custom print label; resolves Align/Spacing control conflict where Spacing silently overwrote Align.
Hide submit button for non-submittable documents
Removes the submit button from form toolbar for non-submittable doctypes, preventing UI confusion.
Escape template context values before rendering
Escapes template context values to prevent XSS in dynamic template rendering.
Escape list filter values before rendering
Escapes list filter values before rendering to prevent XSS through filter UI.
Allow safe tags only in discussion reply md
Restricts HTML tags in discussion replies to a safe allowlist, blocking XSS.
Escape script context values before rendering
Escapes script context values in form rendering to prevent XSS attacks.
Capture HR product usage & activation telemetry
Adds anonymous site-scoped telemetry to measure HR feature usage and post-install activation funnel.
Schedule interview dialog on job applicant form
Replaces broken "Create Interview" button with "Schedule Interview" dialog that collects all details and creates the interview directly.
Show Holiday List Assignment in Employee connections tab
Adds Holiday List Assignment to Employee document's Connections tab so HR users can see assigned holiday lists without navigating away.
Builder UI polish + settings consistency
Polishes Forms builder UI to match SLA/Assignment Rule settings pages and fixes minor UX issues.
Add fields to store Raven keys in Press Settings
Adds fields to Press Settings for storing Raven keys.
Fix conflict, plans section fields got added twice
Fixes press_settings.json conflict where plans section fields were duplicated.
Match correct column name to avoid null
Fixes column name mismatch in signup flow that was causing null errors.
Misc features
Adds method call verb, drops confirmation prompts, improves default behavior and debug hints.
Remove claude's system prompt in assistant mode
Removes Claude system prompt from frappectl assistant mode.
Add frappe-ui molecules directory to tailwind content glob
Adds frappe-ui molecules to Tailwind content glob so utility classes are generated.
Remember selected panels & open file in editor
Persists selected panels and open file in Studio editor across page refresh.
Roll back failed and cancelled app/site tasks via callbacks
Extends task manager callbacks so failed or cancelled tasks roll back to clean state instead of leaving orphans.
Billing invariant audit
Adds billing invariant violations report that surfaces rows with inconsistent team/amount pairs for audit verification.
Add "Filter messages like this" action
Adds "Filter Messages Like This" action to message more-actions menu to scope mailbox to sender, matching Gmail's feature.
Read-only mode for view-only access
Surfaces write permission at load time and renders proper read-only mode for view-only access instead of misleading editable UI.
Outline the active filter's range on the grid
Draws Google-Sheets-style outline around active filter's rectangle to visually indicate which cells are filtered.
The core ↔ service boundary — VMService seam + satellite
Lands phase 0 of core/service boundary: Atlas core keeps VM existence; service-specific logic attaches via explicit registry.
Add filesystem path tab completion
Adds filesystem path tab completion for bench commands like restore, backup, and data-import.
XLOOKUP, in-cell parameter help, and warn-severity validation
Adds XLOOKUP function with exact/next-larger/next-smaller modes, in-cell parameter hints, and validation with warning severity.
Custom Excel-style number formats
Adds custom number format type allowing Excel-style format codes beyond built-in presets with interpreter covering common codes.
Web Application Firewall
Implements web application firewall functionality for Pilot.
Canvas unification — Phase 3a: unified toolbar + drawable whiteboard
Makes unified canvas fully drawable by showing both block creation and whiteboard annotation tools in bottom palette with shared tool namespace.
Canvas unification — Phase 2b: simultaneous block + whiteboard rendering
First visible step of canvas unification: renders shared block substrate and whiteboard layer together so shapes and ink coexist on one canvas.
Canvas unification — Phase 2a: tool-keyed interaction dispatcher
Converts surface interaction registration from single-slot ref into layer-keyed registry resolved by active tool.
Canvas unification — Phase 1: unified-document data model
Introduces unified data model for all diagram types (blocks, shapes, whiteboard ink, stickies) as first phase of canvas unification.
Re-parse a released source instead of serving it from cache
Repurses FileTallySource after release instead of serving stale cache, fixing buffer reuse bugs on re-runs in same worker.
Don't nest stale params into contact search filter
Fixes malformed JMAP filter in contact autocomplete where search text was being replaced by stale params object.
Mount FrappeUIProvider in slides shell
Mounts FrappeUIProvider in slides shell and migrates deprecated toast.create calls to new toast API.
Don't apply hover bg when row is fully overridden via slot
Prevents tree component from applying default hover background when row content is fully customized via slot.
Cap stored attachment text to avoid exceeding max_allowed_packet
Caps attachment text storage to inline-injection threshold while preserving full text in memory for retrieval and embedding.
Wrap inline images in multipart/related
Restructures MIME message layout to wrap inline images in multipart/related, resolving AWS Trust & Safety rejection of mail replies.
Credits negative balance
Fixes currency-blind credit anchor that allowed per-currency balances to go negative while the guard approved debits.
Thursday, July 16
Add on hold status to project
New Project status for temporarily pausing a project without marking it cancelled.
Name every conflicting voucher in the reserved batch error
Reserved Batch Conflict error named only the first conflicting voucher; now lists every voucher with an outstanding claim.
Allow delivery when a batch is reserved across multiple sales orders
Delivering one order's own reserved batch unit threw Reserved Batch Conflict when another order's reservation exactly matched the remainder; now aggregates outstanding reserved qty across all orders.
Set correct currency in supplier quotation net rate field
Supplier quotation net rate field used the wrong currency context, showing values in the wrong denomination.
Hide job card field in purchase order item
fix: hide job card field in purchase order item
Validate mandatory date filters in reports
Dashboard charts on reports lacking mandatory date filters raised TypeError instead of displaying a user-friendly validation message.
Apply user permissions via build_match_conditions
`sales_person_wise_transaction_summary` report broke after backport #56429; rebuilt filters using plain dicts and `build_match_conditions` for compatibility.
Skip redundant reposting of dependent items
Cascading reposting of dependent items after a backdated entry caused items to repost multiple times if they had their own queued repost records.
Preserve UI sorting in report view export
Report export now preserves the sort order from the UI by passing visible column indices to the backend.
Barcode scanner enhancements
Added flashlight toggle, zoom in/out, and keep-scanner-open options for mobile barcode scanning.
Feat!: move classic print formats to the new builder and remove the classic builder
Default printing now renders via the beta Chromium-based builder; classic layouts auto-convert on migrate with reversibility via `classic_format_data`.
Center selected-icon with input text
fix(icon-field): center selected-icon with input text
Don't crash query validation on large generated queries
Query validation crashed on large `IN (...)` filters exceeding sqlparse's `MAX_GROUPING_TOKENS` cap; now raises a clearer error.
Evaluate creation-based SQL cutoffs against the system timezone clock
Raw SQL queries compared timestamps against `NOW()` in DB timezone instead of system timezone, causing mismatches when the two differed.
Batch name lookups in get_data_for_custom_field
Custom report link columns with thousands of values exceeded sqlparse's token limit, crashing with SQLParseError; now batches lookups per 1000 names instead of one query per list.
Skip push notification config fetch without relay
Every HRMS PWA tried to fetch the notification relay config even when unconfigured (common on self-hosted instances), raising an error.
Quote from_date and to_date to resolve reserved word errors
MariaDB 12.3+ treats `to_date` and `from_date` as reserved words, causing 1064 Syntax Errors in raw SQL queries; now backtick-quoted.
Default amount incorrectly prorated in formula-based components
Default component amounts were incorrectly recalculated using payment days instead of total working days when LWP or absences affected payment days.
Cancelled Shift Assignments silently block new shift creation via Roster API
Cancelled shifts kept their `status = 'Active'`, so the adjacency filter still matched them, blocking new shifts; now updates status on cancel.
Half-yearly earned leave schedule for joining date based assignments
Half-yearly leave allocation calculated period boundaries against the calendar year instead of the employee's actual joining date.
Ticket SLA policy application
Enabled SLAs with a blank condition matched every ticket, silently overriding the default SLA.
Add 'how did you hear about us' question
feat(persona): add 'how did you hear about us' question
Don't send null docname on lesson file upload
File uploads on unsaved lessons failed with HTTP 417; now uploads as standalone files until the lesson is saved.
Stop fetching the outline before the course loads
Course outline fetch fired before course name was available, returning 500 and never retrying; now uses a watcher that fetches only once course data loads.
Miscellaneous fixes across payments, jobs, assignments, batches, and editor
Fixed 7 bugs: payment gateway validation, applicant count sync, assignment deadline, batch creation, and lesson editor field visibility.
Web Form Builder in Frontend
Built-in form builder for CRM to create public forms that collect leads and deals directly from websites, with visual builder, field selection, and automation.
Normalize user names for mentions
Mentions in comments broke in prod builds due to missing username normalization.
Rebuild sales quotation funnel with builder ops
Only raw-SQL query across shipped templates; rebuilt as 100% builder-native ops mirroring existing accounting patterns.
Re-base accounting AR/AP on Payment Ledger Entry
AR/AP Open Invoices queries scanned unbounded GL Entry (tens of millions of rows); rebased on smaller Payment Ledger Entry.
Lower default query timeout to 60s
Interactive query timeout reduced from 180s to 60s to prevent stalled workers and unnecessary OLTP load; timeout now routes through a single helper.
Nudge Insights Admins to prebuilt module dashboards
Dismissible banner in ERPNext module workspaces (Selling, Buying, Stock, Financial Reports) linking Insights Admins to prebuilt dashboards for each module.
Allow multiple selection for apps removal in benches page
feat(ui): Allow multiple selection for apps removal in benches page
Check the public ip address field instead of check box
fix(sync): Check the public ip address field instead of check box
Repair resize tests for the host memory reserve + satisfy pinned ruff
Greened failing Server and Frappe Linter CI jobs after placement's host memory reserve change; fixed resize capacity tests and ruff violations.
Clarify external vs pilot-managed DB in setup wizard
Root password field now describes three cases (fresh, pilot-managed, external); prefills host/port for external databases.
Connect setup wizard to an external database server
Optional toggle to connect to external database (RDS, etc.) instead of spawning a pilot-owned MariaDB/PostgreSQL; explicit stored choice with prefilled defaults.
Show repeater icon on a repeater/repeated block to visually identify them
feat: show repeater icon on a repeater/repeated block to visually identify them
Show tool calls immediately while streaming
Tool cards appear immediately mid-stream with the call name, then re-emit with full arguments once they finish streaming.
Redesign marketplace page
Visual redesign with category pills (7 buckets from registry), "Works with" filter for Frappe-made apps, import button in filter row, and grid improvements.
Archive shortcuts + optimistic theme cycling & undo-toast cleanup
Added `G` then `A` shortcut to Archive mailbox and documented both Archive shortcuts; plus optimistic theme cycling and undo-toast cleanup.
Search across accounts
Opt-in toggle to search across all JMAP accounts the user owns, with results merged newest-first.
Search filter chips, quick filters & inline editing
Mail search UX overhaul with redesigned results header, active-filter chips, inline operator autocomplete (for folders, contacts), and quick-filter bar.
RS256/JWKS trust anchor + bootstrap-token enrollment
Central mints a single RSA signing key for JWT tokens benches trust, with a JWKS endpoint and bootstrap-token enrollment flow.
Get app validations
Refactored app validator into a pluggable package with checks for repo structure, syntax, dependency declarations, and static import resolution.
Managed add on services
Adds Services module to Central for team-level add-ons, starting with LLM Hosting (Grove-backed) with catalogue, entitlements, credentials, and billing.
Raise toast z-index above sticky columns
fix: raise toast z-index above sticky columns
Allow deleting Flow Model despite Session/Agent references
Sessions and Agents held historical links to Flow Models, blocking deletion; added them to `ignore_links_on_delete`.
Wednesday, July 15
Batch BOM source warehouse lookup in get_production_items to avoid N+1
Fetches all BOM source warehouses in a single query instead of one per Production Plan item row.
Make naming series based on posting datetime on by default on new sites
New ERPNext v17 sites now have posting-datetime-based naming series enabled by default.
Company-wise restriction for Item, Customer and Supplier masters
Item, Customer, and Supplier now support company-wise restriction; masters are hidden from users limited by Company User Permissions when feature is enabled.
Duplicate scorecard period when supplier is created on a month end
Supplier scorecards created on month-end dates no longer generate duplicate periods.
Prevent duplicate material request items in purchase order
Purchase Orders created from Material Requests now allow the same item in multiple rows with different rates, matching Sales Order from Quotation behavior.
Preserve job card transferred quantity
Job card quantity is now preserved during transfer operations.
Set stock_uom on transferred Stock Reservation Entries
Transferred Stock Reservation entries now correctly copy stock_uom, preventing silent UOM mismatches on items with non-default stock UOMs.
Added permission checks on `get_account_balances_coa`
Adds missing permission enforcement to Chart of Accounts balance endpoint.
Workspace rail
Adds workspace dock on the sidebar for displaying and navigating workspaces.
Add Letter Head to Printing workspace sidebar
Letter Head doctype now appears in the Printing workspace sidebar.
Bump phonenumbers to ~=9.0.23
Upgrades phonenumbers library to correctly validate Saudi Arabia phone numbers with widened mobile pattern.
Ignore not nullable and v15 specific module fetching
Fixes database column handling and v15-specific report module fetching logic.
Consider ownership check & perms. when using dot notation
Database queries using dot notation now properly enforce ownership and permission checks.
Allow child tables to be used in dashboard charts
Chart Dashboards on child doctypes are now accessible to users with appropriate permissions.
Preserve ui sort order for query report
Query reports now preserve user-set sort order instead of resetting to default.
Update category retrieval to use `form_dict` pathname
Help article categories are now correctly retrieved when accessed via URL routing.
Guard against invalid navigator.language in alt shortcuts
Alt shortcut initialization no longer crashes when browsers return invalid BCP-47 language tags.
Restore telemetry via boot_config + track library adoption
Telemetry now works via boot_config pulse client, independent of frappe-ui v1 migration.
Workbook template updates via version + checksum
Workbook templates can now update in-place from the library; pristine copies auto-update on migrate, edited copies get warned manual updates.
Deploy Wazuh
Adds Wazuh security monitoring deployment to Press servers.
Add support for freemium plan
Site plans now support lifetime free subscriptions via negative trial days in product trials.
Infinite scroll for All Inboxes
All Inboxes view now uses infinite scroll instead of offset pagination with collapsible date groups.
Add find-doc-save-hooks.sh
Utility script surfaces app-side document save hooks that impact performance.
Load-aware host selection (part 1) for the proportional size ladder
VM placement now scores feasible Active hosts under operator-chosen strategies (Spread by default) and selects the best.
Optimistic UI for thread & message actions
Mail actions (archive, trash, star, read, move, etc.) now update UI before server confirms, with automatic rollback on failure.
Backup retention management and audit logging
Adds backup retention policies and audit logging for backup management operations.
Template categories, responsive layout fixes, and catalog cleanup
Template picker now organizes templates into four categories (Marketing, Portfolio, Editorial, Local Business) with responsive improvements.
Select & edit multiple blocks
Multiple blocks can now be selected with Shift+Click (range) or Cmd/Ctrl+Click (toggle) and edited together if same component type.
Set Route Variables for editing/testing dynamic route pages
Studio now allows setting route variables for testing dynamic pages, replacing non-deterministic first-document fallback.
Note server scripts requirement for script tools and conditions
Adds documentation that Flow script tools and conditions require `server_script_enabled`.
Sandboxed trigger conditions and a Run As identity
Flow trigger conditions now run in server-script sandbox (multi-line scripts with result variable) and triggers can run as a specified identity.
Back up VM snapshots to S3 and restore them
Adds off-host durability for VM snapshots via point-in-time S3 backup/restore, supporting both cold (disk) and warm (memory + signature) snapshots for clone rehydration.
Install base packages on macOS via Homebrew too
macOS now installs base tools, databases, and Node through Homebrew with proper sudo prompting and download validation.
Bench new picks a MariaDB port macOS will never actually bind to
Bench new on macOS no longer picks custom MariaDB ports that Homebrew won't use.
MacOS is_provisioned() always False, silently resetting a secured DB password
Database provisioning checks on macOS now work correctly, preventing silent password resets on second bench init.
Fail the bake loud when the freshen unit isn't live at capture
VM snapshot bake now fails loudly if freshen unit isn't alive, preventing silent guest reachability issues.
Cap old-order sync at 31 inclusive days with precise day bounds and tests
Old order sync respects Unicommerce's 31-day search limit with precise day boundaries and client-side validation.
Restore screen share after recovery
Screen sharing is now restored after video meeting recovery.
Route reconnect lifecycle events
Media reconnection events are now correctly routed after connection recovery.
Bound SFU request acknowledgements
Prevents unbounded SFU request acknowledgement queues in video meetings.
Recover media after signaling and ICE failures
Video meetings now independently recover transports after signaling and ICE failures, resync participants, and preserve E2EE state.
Tuesday, July 14
Using get_cached_doc to retrieve template for get_terms_and_conditions
fix(tnc): using get_cached_doc to retrieve template for get_terms_and_conditions
Preserve job card transferred quantity
Work Orders with multiple Job Cards showed incorrect quantity in progress by adding quantities from every card instead of using the final effective quantity.
Restrict jinja globals in process statement of accounts templates
fix: restrict jinja globals in process statement of accounts templates
Match quoted and unquoted sort/group references to child tables
fix: match quoted and unquoted sort/group references to child tables
Discover methods
API discovery now includes controller methods alongside RPC methods with tagged union to distinguish.
Retry failed deliveries on a backoff schedule
Webhook retries now use separate background jobs with increasing backoff instead of sleeping in same job; prevents worker blocking.
Virtualization and pagination in kanban board
Kanban board now virtualizes and paginates instead of loading all documents at once; solves initial load slowness and freeze on scroll for large datasets.
Add SafeDoc class
SafeDoc class extends _dict with internal Document methods for safer eval contexts.
UX misleading as there is no cap in backend
fix(email_report): UX misleading as there is no cap in backend
Warn and auto-clear disabled default print format
Disabling a default Print Format left it silent and confusing; now warns via confirm and auto-clears on save.
Prevent child row identity corruption on sync after reorder
Child table rows could become misaligned after save if backend reordered or removed rows; reconciliation now matches by document name instead of array index.
Avoid false matching custom queue name with default ones
Custom queue named `schedulelong` would false-match under `queue=long` via endswith check; switched to exact match.
Password strength check fails on long random passwords
Pasting long passwords (like manager-generated ones) caused 500 error because error response itself failed to serialize.
List toolbar keeps mobile layout after the viewport gets wider
Layout decision was made once at construction time; resizing window or rotating phone left toolbar stuck in original layout.
Don't block logged-in users from commenting
Bad conflict resolution in backport kept guest-only anti-spoof check in logged-in branch; every logged-in comment was incorrectly rejected with "Please login".
Validate HTTP method for document calls
fix(api): validate HTTP method for document calls
Customer portal permission banner
Dialog to revert end users to access each other's tickets.
Data Enrichment for CRM Lead, Deal and Organization
First-party domain enrichment; crawls company website and extracts structured facts (JSON-LD, Open Graph, meta tags) to enrich CRM records without third-party APIs.
Gate local payment tabs behind role permission
feat(partner): Gate local payment tabs behind role permission
Improve partner onboarding
Added approved_on field, company logo upload, link to Frappe School batches, sales contact in sidebar.
Pull @framework/ui components and upgrade frappe-ui to beta 24
feat: pull @framework/ui components and upgrade frappe-ui to beta 24
Add categories to template group manifests and catalog
Templates can now belong to multiple categories (e.g. Portfolio + Marketing) passed through in catalog for consumer filtering.
Declare Frappe Cloud version compatibility
Added [tool.bench.frappe-dependencies] to pyproject.toml so Frappe Cloud validates app compatibility during installs/updates.
Support Debian, Fedora and Arch alongside Ubuntu and Alpine
Installer now detects distro from /etc/os-release and uses per-distro package primitives (apt/dnf/pacman/xbps/apk).
JWKS-based remote session login
Central can mint tokens for bench login and generate site-login SID via dummy JWKS server.
Gate multi-bench UI/API behind admin.allow_bench_management
feat: Gate multi-bench UI/API behind admin.allow_bench_management
Trusted-proxy nginx gating and local domain validation
fix: trusted-proxy nginx gating and local domain validation
Discover and invoke doctype methods
Extends API discovery to include controller methods; frappectl method list/search now cover new surface.
Protect system-generated rows
Lets apps ship builtin knowledge and system rows managed via migrate-time sync without users breaking them from the Desk.
Stop response
Stop button while response streams to abort and finalize run; deny tool-approval now ends turn instead of continuing.
Import & Export Contacts (JMAP + .vcf)
Submittable Contacts Exchange DocType for background import/export with jmap (round-trippable JSContact) and .vcf (vCard 4.0) formats.
All Inboxes — unified inbox across all accounts
Merges Inbox of every linked account into single newest-first list for viewing personal and shared accounts together.
Replace mailbox pagination with infinite scroll
Next batch appends as you scroll instead of refetching 25-row pages; already-loaded rows never re-fetched.
Preserve party contacts and addresses on dirty phone / GSTIN data
Invalid phone fields and GSTIN state code mismatches were silently losing party email/name on import; now salvaged with validation.
Monday, July 13
Make represents company field in purchase invoice ignore user pe…
fix: make represents company field in purchase invoice ignore user pe…
Allow asset repair creation for fully depreciated assets
Removed restriction preventing asset repairs on fully depreciated assets to allow expense tracking for still-active assets.
Propagate project from job card to stock entry
Added missing project field copy from job card to stock entry in pick list workflow.
Link job card in stock entry created from pick list
Stock entries created from pick lists against job card material requests now properly set job_card, job_card_item, and fg_completed_qty so the job card recognizes the transfer.
Accounting dimension search matching unrelated records
Fixed search matching for check-type dimension fields (e.g., Cost Center) that incorrectly matched unrelated records due to type coercion on non-numeric input.
Zone divider polish, inline title row, drag-resize table columns
Print format builder improvements: zone dividers now show as light-gray labels with "repeats on all pages" hints; inspector controls are inline; table columns support drag-to-resize.
Empty state component
New standard empty state component for list views, dashboards, and reports; replaces duplicate implementations in embedded lists and DocType settings.
Component library
Added a new component library to Frappe Framework with accessibility and security baked in, matching the Espresso design system; includes a Component Explorer page for viewing all variations and sample code.
Fold table colour controls into the style section
Moved table header/border color pickers into Style section alongside field controls; fixed label alignment issues.
Pixel parity between builder canvas and print output
Converted stylesheet spacing from rem to compensated em to match builder canvas rendering against wkhtmltopdf and Chrome output.
Close color picker on outside click and swatch pick
Color picker popovers now properly close on outside clicks and swatch selection; consolidated duplicate color-control mount logic.
Render rating stars from fraction values
Fixed rating field rendering in print builder; values stored as 0-1 fractions now correctly scale to star counts per field options instead of crashing.
Postgres GroupingError when filtering list views by child-table fields
Fixed postgres query generation when filtering by child-table fields with linked reference titles; now properly aggregates or includes link-table columns in GROUP BY.
Correct DocType casing in read tool label
fix: correct DocType casing in read tool label
App validation
Pre-install app validations to ensure internal and external imports are accounted for and directory structure is correct.
Sunday, July 12
Explain FIFO allocation of fixed Discount Amount on Sales Order
Add an informational description to the Additional Discount Amount field explaining how fixed discounts behave across multiple deliveries and invoices.
Allow negative balance in bank statement import
Accept negative opening balances during bank statement imports.
Update events order by date ascending
Sort Lead activities by due date instead of arbitrary order.
Render columnar financial statements
Display data in the Horizontal Balance Sheet columnar report template instead of showing empty results.
Read user permissions from current session user in payment reconciliation
Refresh user permission filters at reconciliation time instead of capturing them at document creation, fixing filters when the session user changes.
Map stock_qty in apply_price_list_on_item
Convert transaction quantity to stock quantity before evaluating Pricing Rules when items use alternative UOMs, preventing quantity-band rules from being inconsistently applied.
Remove incorrect Payable account_type from Customer Deposits in Philippines CoA
Fix non-deterministic default payable account selection caused by duplicate account_type in the Philippines Chart of Accounts template.
Print format builder colour styling + copy/paste
Add colour styling for table headers/borders and field text, plus copy/paste support for fields and sections in the print format builder.
Min_value and max_value properties for numeric fields
Allow Int, Float, Currency, and Percent fields to declare validation bounds in DocType and Customize Form, with validation running on save.
Auto-assignment fails to follow document when triggered by web user
Apply ignore_permissions when creating follow entries during auto-assignment from web user submissions.
Print format builder table + preview fixes
Center serial-number columns, round section backgrounds in print output, and keep preview document selection in sync.
Assign to filter fails with type validation error on strict stacks
Accept current_filters as either string or list to fix type validation when toggling the Group By dropdown in the Assign To filter.
Return consistent request ID
Return a consistent request ID to allow tools to query recordings easily.
"Show all activity" toggle showing white when enabled
Fix toggle appearance when the "Show all activity" filter is enabled.
Duration picker opens away from the field in scrolled grids
Position the duration picker using viewport coordinates and keep it anchored while scrolling or resizing.
Re-evaluate link_filters per search without breaking doc-based get_query
Fix crashes when Link fields have both Customize Form filters and programmatic set_query reading the document.
Guard against None table field in load_doc_before_save
Default to an empty list when child table fields are None to prevent TypeError during pre-save processing.
Clear if_owner on permission rows above level 0
Validate and clear if_owner flags on higher permission levels where they are ignored, aligning stored permissions with framework behavior.
Translations not applied in background jobs
Set frappe.local.lang after initializing the job user so translations use the job user's language instead of the site default.
Harden DCR and cleanup OAuth authorization UI
Improve OAuth Device Code Request security and align UI with design standards.
Add egress URL validation for server-side fetches
Validate egress URLs for server-side fetches to prevent SSRF attacks.
Remove root redirect from website redirects
Stop redirecting the root path to allow users to set their default home URL.
Don't override favicon for mail and calendar
Preserve app-specific favicons instead of overriding them globally.
Don't reload on switching apps
Stop reloading the page when switching between suite apps.
Bump reka-ui to 2.9.9 so dialog inputs focus on mouse click
Upgrade reka-ui to fix a regression where dialog overlays suppressed focus on mouse clicks to inputs and contenteditable regions.
Saturday, July 11
Correct stock ageing value for moving average and lifo items
Stock Ageing report values are now correct for Moving Average and LIFO valuation methods; each remaining slot is revalued to qty × current rate.
Pick list serial batch posting date
Pick list serial/batch handling during posting now correctly applies posting dates.
Pick list serial batch posting date
Pick list serial/batch posting dates are now handled correctly.
Validate planned end date is not before planned start date in wo…
Work Order now validates that planned end date is not before planned start date.
Make trend report based-on and group-by column labels translatable
Trend report column labels for based-on and group-by are now translatable.
Link job card in stock entry created from pick list
Stock Entries created from Pick Lists against Job Card Material Requests now properly set job_card and related fields, so the Job Card recognizes the material transfer.
Fetch payment entry reference amounts from invoice
Payment Entry created from a Payment Request now correctly shows the full invoice amount in the Payment References table instead of only the paid amount from the request.
Add generic utilities for styling and layout
Added generic utility classes for styling and layout based on the Espresso design system.
Add hook to allow drive to overwrite file perms
Added hook to allow Drive to override File permissions independent of Framework defaults.
Expose source code over discovery API
Framework now exposes source code over the discovery API.
Collapsible section collapses while typing in a child table row form
Editing a field in a collapsible section of a grid row was causing the section to collapse; now preserves expansion state during refresh.
Child table header background/radius scoped to row, not cells
Child table header styling now applies to the row instead of individual cells, enabling proper border radius on a rounded container.
Contrast on custom HTML sidebar field in print format builder
Print format builder custom HTML sidebar field now has proper contrast in dark mode.
Dashboard quick list check filter drops "= No"
Dashboard quick list check filters with "= No" were being dropped because standard checkboxes couldn't distinguish unchecked from no-filter; now kept as regular filters.
Bind inline edit to row at edit start, not submit
Report View inline edits were saving to the wrong record if a quick filter changed while editing; now binds to the row captured at edit start.
Scope index subquery to current schema in get_table_co…
MariaDB index metadata lookup was reading from all databases with matching table names instead of just the current schema, breaking multi-site migrations.
Preserve guest-submitted name/email
Guest comments were being overwritten with "Guest" because an anti-spoofing override ran above the guest check; now scoped to logged-in users only.
Don't mutate caller's get_query().filters in MultiSelectDialog
MultiSelectDialog was mutating the caller's shared filters object when reused across searches; now works with immutable filters.
Only allow text in description
Description field now restricts input to plain text only.
Escape computed url in EmbeddedList link column
Escape computed URLs in EmbeddedList link columns to prevent XSS.
Revert "fix: make postgres transactions read committed by default"
Reverted postgres transaction isolation level change.
Use static ?url imports for Leaflet images so the rolldown build can resolve them
Studio build was failing because rolldown couldn't resolve Leaflet image imports; switched to static ?url imports.
Use host name if present when trying to notify users of incoming site archival
Site archival notifications now use the host name when present for better user clarity.
Exclude archived sites' updates from archive block
Bench archival was incorrectly blocked if a site that had been involved in a fatal update was later archived; the guard now excludes archived sites.
Remove duplicate primary btn in CommunicationInfoDialog
Removed visually duplicate primary button from communication info dialog.
Trim guide for agents
CLI guide now focuses exclusively on agent use cases; removed human-centric auth and profile management instructions.
Disable mail account
Users can now disable their mail account; when disabled, an optional Stalwart role from Mail Settings is applied to restrict mail server access.
Launch CLI coding agents wired up for Frappe
Added frappe-cli assistant command to launch CLI coding agents (pi, claude, codex) with Frappe-specific system prompts and site context.
Add self-upgrade command
CLI can now self-upgrade using the original installation backend (uv tool, pipx, pip) with automatic detection of the installer.
Notify when a newer version is available
CLI now passively notifies users when a newer version is available via a one-line stderr nudge, leveraging the existing update command.
Introduce themes for avatar
Avatar component now supports themes with deterministic color assignment by label, defaulting to gray with overrideable options.
Add manual refresh button for new emails
Mail UI now has a manual refresh button for on-demand email fetching instead of waiting for polling.
Route accepted senders to Inbox and let spam fall through screening
Mail screening gate now routes accepted senders straight to Inbox while letting unrecognized mail fall through to server-side spam filtering.
Feat(meet-sfu)!: use `webRtcServer` for minimising port usage
SFU now uses webRtcServer with one port per worker instead of one per transport, dramatically reducing open ports on the server.
Fetch source if available
CLI now fetches source code when available for enhanced introspection.
Add OAuth 2.0 browser login
Added OAuth 2.0 authorization-code + PKCE flow for interactive browser login; access token refreshes automatically and no secret is stored locally.
Dark-mode event colors
Calendar event colors now render correctly in dark mode.
Friday, July 10
Support partial transfer from pick list
Pick list now supports partial transfers with Work Order status updates on each partial completion.
Create material request for raw materials from work order
Work Order form now includes button to create Material Request for raw materials, adding requisition step before transfer.
Confirmation dialog when enabling negative stock on Item
Item-level negative stock toggle now shows same compliance warning as global setting, alerting users to FIFO/valuation implications.
Allow group warehouse for raw material availability in production plan
Production Plan now accepts optional group warehouse for raw material availability checks, allowing stock assessment across sibling warehouses while receiving into leaf warehouse.
Patch moved create_company_custom_fields from pre_model_sync to post_model_sync
Company custom field creation patch moved to post_model_sync for correct execution order.
Match depreciation schedule rows at currency precision to avoid duplicate JEs
Depreciation schedule now matches rows at currency precision instead of exact float equality, preventing duplicate journal entries for assets with many decimal places.
Skip allowed users check when frappe crm is installed locally
CRM sync now handles local CRM installation alongside remote, skipping user allowlist validation and auto-cleaning settings on app install/uninstall.
Revert "refactor(sales_person_wise_transaction_summary)"
Sales Person-wise Transaction Summary reverted to SQL from query builder to fix v15 compatibility (ignore_permissions not supported).
Use company currency instead of global default in report
Trend reports now display company currency symbol instead of global default, fixing symbol mismatches in multi-company environments.
Make trend report column labels translatable
Trend report headers (Item, Item Name, Customer, Currency, etc.) now translatable instead of hardcoded English.
Pick list serial batch posting date
Pick list posting date handling fixed to prevent TypeError and date validation errors in serial/batch operations.
Stock entry handler and transaction controller fixes
Type-hint and module refactors fixed to restore client-side whitelisted method calls for apply_price_list and stock_entry_handler.
Validate planned end date is not before planned start date in work order
Work Order validation now prevents end date before start date.
Rename variant item_code/item_name when attribute abbreviation changes
Item variant codes and names now update when parent attribute abbreviation changes, keeping variants in sync with attribute configuration.
Update BOM operations when routing is changed
BOM operations table now updates when routing is changed on a new version, no longer showing stale operations from original BOM.
Partial delivery note against pick list
Partial deliveries against pick lists now handled correctly.
Surface data import failures in log files
Data import row errors now logged via frappe.logger() for visibility in frappe.log and external log aggregation, complementing Data Import Log.
Basic error analysis
Error analysis UI added for better error visibility and debugging.
Show deferred error insert
Developer experience improvements for error handling.
Postgres Time columns read back with their precision
PostgreSQL Time columns now read back with full precision specification, preventing false type-change detection on every migrate.
Prevent broken pipe from aborting dashboard sync during setup
Dashboard sync now continues if progress stdout fails, making output best-effort instead of aborting setup wizard.
Hide Download Report button without read permission
Download Report button now hidden when user lacks read permission.
Show table field label instead of doctype name in filter dropdown
Child table filters now show parent table label instead of internal doctype name, improving UX discoverability.
Timeline make cards respect full-width toggle
Timeline comment cards now respect full-width toggle setting.
Don't auto-set default on every save, only on create
Letterhead default no longer resets on every save, only on initial creation.
Normalize Check formatter value with cint to prevent 0 rendering as checked
Check field grid cells now normalize string "0" to integer 0 before rendering, preventing false "checked" state in web form grids.
Apply cint to Int fieldtype in format_value
Int columns now consistently formatted with cint on server side, matching client-side formatter and fixing PDF/email report decimal display.
Remove border from filled search bar
Search bar border removed from filled state, eliminating double edge against navbar background.
Queued telemetry events must survive clear_cache()
Telemetry events persisted across cache clear operations.
Dont explode plucked scalars on masked doctypes
Query builder now handles masked doctypes correctly without exploding scalar results.
Allow missing link_filters in validate_fields function
Patch compatibility restored for ≤v14 databases where link_filters column doesn't exist during pre_model_sync.
Child table numeric filters generate invalid postgres query
Nullability checks now performed against resolved child DocType, preventing invalid COALESCE wrapping on PostgreSQL numeric fields.
Xls file import fails with "startswith first arg must be str or a tuple of str, not bytes"
Legacy .xls OLE2 files now preserved as binary, fixing xlrd parsing that failed on text-decoded data.
Code fields show stale value after navigating between documents
Code field editors now repaint when expanded from collapsed sections, fixing display of stale content from previous documents.
Form does not render when form sidebar is disabled
Web Page form rendering fixed when form_sidebar user setting is disabled, preventing TypeError in add_web_link.
Print view is unusable on mobile
Print preview iframe now pinned to actual page width and toolbar repositioned for mobile, preventing content overflow and improving usability.
Notification subject shows "None" when the title field is empty
Notification subjects now use document name fallback instead of literal "None" when configured title field is empty.
Kanban board leaks memory and hangs on repeated re-render
Kanban watchers now properly unsubscribe on re-initialization, preventing memory leak and performance degradation on repeated refreshes.
Restrict print format builder preview to sys. man.
Print format builder API restricted to System Manager role, preventing unauthorized access via preview endpoint.
Link field clears when selected value is outside default options page
Link field values now persist when selected value falls outside default page by injecting value into options and reloading on clear.
Resolve blank employee number and reports_to in Profile
PWA Profile now displays employee_number (when using name-based IDs) and reports_to by bypassing desk-side hiding and permission restrictions.
Implement close warning for job openings and related validation.
Job Opening close now shows confirmation warning if linked Staffing Plan still has unfilled positions, while still allowing close if needed.
Include expense claim line projects in project total expense claim
Project total expense claim calculation now includes expense claim lines linked at the detail level, not just document-level project links.
Show remaining wait time instead of elapsed time for disk resize
Disk resize wait messages now show remaining time (decreasing) instead of elapsed time (increasing), matching user expectations for cooldown UX.
Add Push Subscription tab to Settings
Mail UI Settings now includes Push Subscriptions tab where users can create, view, renew, and delete JMAP subscriptions in bulk.
Show SMTP/IMAP/POP details for third-party clients
Mail Settings now displays SMTP/IMAP/POP configuration for third-party mail clients (Thunderbird, Gmail app), configurable via admin Mail Client Configuration table.
Add push encryption toggle and fix encrypted push decoding
JMAP push encryption now toggleable (unencrypted by default), and encrypted push decoding fixed to handle base64 body with JSON content-type.
Add daily job to renew expiring JMAP push subscriptions
Daily scheduled job now renews JMAP push subscriptions within 3-day expiry threshold, preventing subscription lapse.
Add read-only profiles
CLI profiles now support --read-only flag to restrict operations to GET requests only, preventing accidental writes.
Use indiacator pill for styling status fields
Status field styling now consistent using indicator pill component.
Remove non-standard "Payroll Manager" role from reports
Non-standard "Payroll Manager" role removed from lwf_register, esic_register, bank_mandate_report, and employee_provident_fund_register permissions.
Resolve lock-wait timeouts and cut repost overhead in loan write off and repayment repost
Bulk loan write off and repayment repost operations now execute with batching and async reposting instead of single long transaction, eliminating lock timeouts and reducing runtime from hours.
Resolve avatar/presence user from shared session store
Sheets app avatar now displays correct user initials instead of literal "U" by resolving session from shared store instead of window.frappe.
Relocate email templates to suite app root
Email template loading fixed by relocating templates to app root, restoring frappe.sendmail(template=...) functionality.
Thursday, July 9
Add grouping by dimension functionality in financial reports
Financial reports now support grouping rows by custom dimensions.
Move microbenchmarks to Frappe project
feat: Move microbenchmarks to Frappe project
Add validation for link filters to ensure valid JSON format and structure
Added backend validation for link_filters on fields to ensure valid JSON structure.
Show link filters if fieldtype is Link
Link filters field now appears in Custom Field configuration when fieldtype is Link.
Apply default ordering in v1 & v2 list endpoints
REST list endpoints now apply stable default sort order instead of returning records in undefined order.
Add Verify SSL option for JMAP connection
Added Verify SSL checkbox to Mail Settings for JMAP, enabling local development with self-signed certificates.
Add date-range old-order sync with paginated fetch and duplicate-safe creation
New on-demand backfill job fetches and syncs Unicommerce orders within a date range with pagination and duplicate safety.
Add --debug to trace requests and server SQL
Global `--debug` flag now traces HTTP traffic and server SQL to stderr (with API keys redacted).
Markdown format for useEditor and
Markdown-backed apps (wikis, docs) can now use `format: 'markdown'` with content carried as markdown string.
Default list sort to 'creation desc'
`frappe doc list` now defaults to newest documents first unless otherwise specified.
Map PY state to Puducherry to match ERPNext state list
Unicommerce orders shipping to Puducherry now map to the correct ERPNext state name.
Refresh access token on 401 and retry once so long-running syncs survive token expiry
Long-running Unicommerce sync jobs now refresh expired tokens on HTTP 401 and retry instead of aborting.
Bump `dnspython` to ~=2.6.1 (PYSEC-2026-1307)
fix: bump `dnspython` to ~=2.6.1 (PYSEC-2026-1307)
Wednesday, July 8
Precision issue causing reconciliation error
Fixes floating-point precision errors that blocked account reconciliation. Backported to #56937, #56938.
Validate template and its variant in the same Pricing Rule
Prevents false "Multiple Price Rules exist" error when both a template and its variant are added to the same rule, with a save-time validation block.
Added permission checks on various whitelisted functions
Adds read permission validation to payment entry detail lookups, bank account, and party account whitelisted functions.
Remove unnecessary validation in Release Group doctype
Removes an overly restrictive validation check in Release Group. Backported to #6918.
Add Plan History tab to site detail page
Shows chronological log of all plan changes with plan details, who changed it, and colour-coded change type (Initial/Upgrade/Downgrade).
Add a Subscriptions tab to view the team's subscriptions
Adds consolidated Subscriptions view under Billing, grouped by type (sites, servers, marketplace apps), showing plan and installed-site tracking. Backported to #6915.
Add missing dependent apps to release group
Automatically appends required dependent apps to release groups if missing, preventing manual configuration gaps. Backported to #6916.
Sync app source versions from repo on branch change
Automatically syncs app source versions when branches are switched. Backported to #6920.
Generate preview from HTML body
Enables preview generation from HTML body content in email and calendar exports.
Mail and calendar export
Restores export functionality for mail and calendar items.
Tuesday, July 7
Prefill value from lead while converting to deal
Prefills conversion modal with lead data to reduce data mismatch risk and improve UX.
Agentic ops, Code & Data wiring
feat(AI Integration): Agentic ops, Code & Data wiring
Recipes gallery homepage + frappe-ui design skill
Adds homepage gallery with eight full-page app screens in desktop and mobile variants, live preview/code switcher, and frappe-ui design guidance.
"Open in ChatGPT/Claude" uses wrong page URL after sidebar navigation
Makes AI share link URLs reactive to SPA navigation instead of binding once at render.
Set max sub category or category max amount while declaring exemptions
fix: set max sub category or category max amount while declaring exemptions
Recover from malformed tool-call arguments
Treats invalid JSON in tool-call arguments as an error result instead of crashing the Flow Run, allowing weaker models to retry.
Report dynamically-mandatory fields in read_screen
Reports fields made mandatory at runtime (via toggle_reqd or mandatory_depends_on) by reading live docfield state instead of static metadata.
Don't flag valid third-party links as broken (#575)
Adds User-Agent header to requests and treats 401/403/429 auth wall responses as valid links rather than dead links.
Fix(SendCloud)!: update deprecated endpoint and parcel validations
Updates deprecated SendCloud endpoint and removes strict parcel dimension validation that blocked rate fetch and label creation for carriers with flexible requirements.
Monday, July 6
Keep bom_no/is_phantom_item pair coherent in get_bom_items_as_dict
When a BOM lists the same item via both phantom and non-phantom sub-BOMs, independent Max() aggregations could pair one line's phantom flag with another line's bom_no, exploding the wrong sub-BOM.
Compute budget requested amount per row
Budget checking was computing Sum(qty) × Max(rate) over all matched Material Request items, fabricating totals when items had different rates; now sums per-row (qty × rate).
Make Procurement Tracker rows coherent PO lines
Multi-line POs with blank material request items were fabricating rows by pairing one line's item with another line's qty and amount; now uses a subquery to pick the representative line per group.
Show earliest schedule date as required date
When a Material Request lists the same item on multiple rows with different schedule dates, the consolidated Requested Items report now shows the earliest date instead of the latest, correctly reflecting urgency.
Campaign with a naming series breaks the UTM Campaign link
When a Campaign uses a naming series, linking to the mirrored UTM Campaign would fail because the link pointed to `campaign_name` instead of the actual document `name`.
Use transaction-currency outstanding on Dunning for foreign-currency invoices
When a Sales Invoice is posted in a foreign currency against a receivable account in the company currency, creating a Dunning now shows the correct outstanding amount in the transaction currency instead of the party account currency.
Stock Closing Entry duplicate check misses contained date ranges
The duplicate-date validation had a logically inert third condition that never fired, allowing a new date range fully contained within an existing entry to slip through.
Close postgres locking races; gate batch valuation with a txn advisory lock
Fixes two phantom-insert races where concurrent operations could create duplicate stock entries on postgres; gates batch valuation with transaction-scoped advisory locks.
Scope Production Planning arrival qty to open POs
The report's Arrival Quantity was summing every submitted PO line ever created including fully received ones, overstating incoming stock; now sums only open POs.
Add v2 discovery API
Internal (WIP, no-docs) API v2 endpoints for programmatic endpoint discovery; OpenAPI compatibility left for external apps.
Add transaction-scoped advisory lock
`frappe.db.transaction_advisory_lock(key)` for postgres: released on transaction commit/rollback, participates in deadlock detection, re-entrant, and shared polling timeout with session-scoped locks.
Print view crash on direct load
Opening `/app/print//` directly threw TypeError because a method reference no longer exists, aborting `print_view.show()` and leaving the page half-rendered.
Wrap write_only inner fn
Internal function wrapping fix for write_only decorator.
Avoid field masking when permissions are ignored
Field masking now respects when permissions are explicitly ignored in queries, returning unmasked data where intended.
Image and barcode blocks with width option
Print Format Builder now supports Image and Barcode blocks; linear barcodes via JsBarcode (browser print), QR codes via pyqrcode server-side as data-URI PNG.
Skip error log for expected exceptions
Adds `skip_error_log` flag to exception classes so expected/benign errors don't clutter the Error Log.
For OCI, revert the VNIC route table in static IP allocation
OCI cleanup: reverts VNIC route table after static IP allocation.
Extend NAT into OCI
Extends NAT (private IP) support from AWS/Hetzner/DO/Frappe Compute into OCI; upgrades OCI SDK from 2.116.0 to 2.180.0 to support VNIC route table attachment.
Add API method discovery commands
`frappe-cli method search|list|show` backed by Frappe's API v2 discovery endpoints; supports `--json` for raw payload or human-readable output.
Require explicit site for non-interactive multi-profile runs
When multiple profiles are authenticated and the CLI runs non-interactively (piped output), it now requires explicit `-s/--site` or env vars instead of silently falling back to the configured default.
Enhance event logging and delivery mechanism
Adds "queued" and "rolled_back" event statuses, implements retry logic for committed events, and enhances logging with timestamps.
Replayable fixture for demo data
Replaces imperative demo generator with deterministic fixture: same forum every seed, timestamps re-anchored to "now", requires no LLM or network.
Don't make newly authenticated sites the default
`frappe-cli auth login` now defaults to `--no-default`, so new sites don't automatically become the default; pass `--default` to opt in.
Resolve VM image from frappe_version
VM provisioning now resolves the OS image based on frappe_version.
Host dashboard shipped under socket activation
Per-host read-only dashboard: Vite/Vue SPA with a stdlib-only backend serving live `/api/state`, organized around Overview/Machines/Images/Storage/Network/Firewall/System sections.
Resize_capacity — per-host headroom for an in-place resize
In-place VM resize now gates on per-host free room (ceiling = host.free + vm.own_footprint), not fleet best-host headroom; includes `placement.resize_headroom()` and whitelisted `provision.resize_capacity()`.
Reconfigure sites with a shorthand name and description
New `frappe-cli auth configure ` to rename and/or describe existing authenticated sites without re-entering credentials.
Remove em-dashes and other AI-speak from demo content
Removed 46 em-dashes and related AI-generated phrasing from demo fixture and seeding docs, replacing with natural alternatives (46 in fixture, 27 in docs, 8 in code).
Respect theme in meet home and shortcut dialog changes
Meet home and shortcut dialogs now respect the user's theme setting.
Follow redirects instead of hard-failing
FrappeClient now follows 3xx redirects (like trailing-slash normalization) safely, since httpx strips Authorization headers on cross-origin redirects.
Operate the Desk frontend from the Flow panel
Adds client tools (read_screen, navigate, fill, submit, etc.) so the panel agent can drive the Desk frontend directly — reads the current route and form state, then manipulates fields and submits.
Sunday, July 5
Shop floor interface for operators
Touch- and keyboard-friendly screen for factory floor supervisors and machine operators to view work orders and manage job lifecycle.
Warning message for new item standard cost
fix: warning message for new item standard cost
Item form permission errors
Opening an Item form as a user with read access but no access to Item Price/Warehouse threw unhandled permission error popups instead of hiding restricted sections.
Reset_mode_of_payments raises AttributeError on a POS Invoice
Calling reset_mode_of_payments on a draft POS Invoice raises AttributeError because the method checks `doc.is_created_using_pos`, a field that only exists on Sales Invoice.
Type cast error on postgres
Clicking on cost center field throws error; Postgres doesn't support `like` operator on `smallint` fields.
Standard helper to render buttons
`frappe.ui.button(opts)` creates Espresso-style button wired with onclick handling, promise handling, and loading states; also available as markup via `.html(opts)`.
Preserve tree view expansion state on back-navigation
Opening a tree, expanding nodes, then navigating back always rebuilt the tree from root, collapsing every expanded node.
Remove outer table border in plain style print output
Bootstrap's `table-bordered` double-bordered the header in plain table style and didn't match the builder preview; removed outer border and standardized header underline.
Add section margin support with per-side spacing control in print format builder
Adds margin support for sections rendered in builder preview and print output; replaces four-stepper padding grid with reusable SpacingRow component; adds table border options.
Show user picker for assignment filter values
Filtering by Assigned To or Liked By required manually entering exact email; now shows a User Link picker for search and selection.
Settings dialog panel scroll
Settings dialog scrolling broke when there were multiple entries and some setting was enabled.
Make field cards fully draggable in print format builder
Drag fields by the whole card instead of only the grip handle; interactive elements are excluded; shows grab/grabbing cursor; browser back closes preview.
Redirect space URL to first page in sidebar order
Visiting a space URL redirected to the first descendant in NestedSet order, not the first page in sidebar sort order; now walks the same tree the sidebar renders.
Hide model api key/base url when a provider is linked, clarify field help
Model form showed API Key and Base URL fields even when a Provider was linked, though the Provider already supplies both.
Undo of an external paste reverts only the anchor cell
Pasting a multi-row text block into a single cell worked, but undo removed only the anchor cell and left every other pasted row.
Redesign the assistant chat and tool-call UI
Sequential non-approval tool calls collapse into one line; arguments render as a compact table; approval requirement now comes from agent's tools instead of hardcoded frontend.
Surface knowledge base descriptions to the agent in the search tool
Flow Knowledge Base `description` field now fed to the model; appends each bound KB's title and description to search_knowledge tool so agent knows what knowledge exists.
Paste tables from external apps via the HTML clipboard flavor
Sheets can now paste structured tables from Excel Online, Google Sheets, Gameplan, or web pages; prefers HTML flavor over tab-delimited plain text.
Add checkbox cells
Google-Sheets-style checkboxes in Sheets; a new data-validation rule that reuses existing validation engine and renders as canvas chips.
Delete linked flow runs when a session is deleted
Deleting a Flow Session left its Flow Runs orphaned; now cascade-deletes linked runs in `FlowSession.on_trash`.
Saturday, June 13
Frappe hardens its test suite with a large batch of new assertions
Adds comprehensive assertions to critical code paths to improve regression detection.
Frappe ships a native Python SocketIO server, cutting realtime memory use
Adds Python-based SocketIO server replacing Node.js to reduce memory usage by running under the gunicorn master process.
Generate preview images from HTML or URLs with bundled Chromium, no external service
Adds native preview-image generation from HTML/URLs using the framework's bundled Chromium, eliminating external service dependencies.
Banker's rounding now handles negative numbers correctly
Fixes sign-blind tie-detection in Banker's rounding that caused -647.325 to incorrectly round to -647.33.