A consultant logs a week across two client projects on one timesheet. You raise a Sales Invoice for the first project, and ERPNext marks the entire timesheet billed — including the hours for the second project, which you haven't invoiced and now can't. The billable work is still there; the system just believes it's already been charged. This guide shows why it happens, the invoicing route that bills one project without touching the others, and how to recover hours a workspace invoice has already locked.
Running a services or software business on ERPNext?
Timesheet billing is core to project-based firms. If you're evaluating ERPNext for that model, ERPNext for IT and software companies covers the wider fit; this post is the specific billing gotcha.
The worst billing bugs don't lose you an argument with a client — they quietly stop you invoicing work you actually did. I am Manoj, ERPNext and Frappe implementation lead at Mith Tech in Bengaluru, and this one turns up in every services firm that puts more than one project on a timesheet.
What actually happens
An ERPNext timesheet holds time logs, each of which can carry a project and a billing rate. When you invoice from that timesheet, ERPNext marks the consumed time logs as billed so they can't be charged twice — a sensible guard against double billing.
The behaviour in #44167 is that when you create a Sales Invoice via the Sales Workspace and use Fetch Timesheet to pull one project's hours, ERPNext marks the whole timesheet billed rather than only the hours you invoiced. If that timesheet also carries hours for other projects, those hours are now flagged billed despite never being invoiced — and because the guard against double billing is exactly what's been tripped, you can no longer invoice them. The report notes the problem does not occur when the invoice is created directly from the project, which is the key to the workaround.
The issue is closed without a linked fix, so this post treats it as a behaviour to verify on your version and route around, rather than a bug with a patch to install. The reader action — invoice from the project, or split timesheets per project — is correct on any version, so the fix status doesn't change what you do.
Enter the hours per project and your rate, then toggle the invoicing route to see how much billable work each route strands.
Invoicing Project A via the Sales Workspace marks the whole timesheet billed, so Project B's 8 h — ₹12,000 of billable work — can no longer be invoiced. That revenue is stranded until the timesheet is corrected.
Models the behaviour in frappe/erpnext #44167 (closed, no linked fix; reported on v15.41.1). Verify on your own version before relying on it.
Verify the behaviour on your version before building a process around it
Because #44167 is closed without a documented fix, confirm it on your instance first: log a test timesheet with hours on two projects, invoice one via the Sales Workspace, and check whether the other project's time logs are now flagged billed. That single test tells you whether you're affected and whether the routing workaround is needed on your version.
Which invoicing route to use
The whole fix hinges on how you raise the invoice, so decide it deliberately rather than letting each biller choose.
Choose how your timesheets and projects are structured to see which invoicing route avoids stranding hours.
Pick how your timesheets and projects are structured.
For a single-project timesheet, the route doesn't matter — marking the whole timesheet billed and marking that project's hours billed are the same thing. The trap is specific to timesheets spanning projects, and there the answer is to invoice from the Project rather than the Sales Workspace, so only that project's hours are consumed. The most robust option, where your process allows it, is to keep one timesheet per project — then the behaviour cannot arise regardless of route, which matters for firms billing many clients from shared staff, the pattern in our IT and software companies guide.
Fix it
Copy-paste the diagnosis, the per-project invoicing route, the recovery steps for a timesheet already locked, and the habits that prevent stranding.
Confirm the whole timesheet was marked billed when only one project was invoiced, before you change how you invoice.
1. Open the Timesheet that won't let you invoice the
remaining project.
2. On each Time Log row, check the "Is Billable" and
"Billed" state:
• Rows for the invoiced project: Billed = yes
• Rows for OTHER projects: Billed = yes ← the bug
(they should still be un-billed)
3. Look at how the paid invoice was raised:
• Sales Workspace > new Sales Invoice > Fetch
Timesheet → marks the whole timesheet billed
(the #44167 path)
• From the Project → marks only
that project's hours
4. If other projects' rows are billed and were invoiced
via the Sales Workspace, that is #44167.Confirm the whole timesheet was flagged
Open the timesheet that won't let you invoice the remaining project and check the billed flag on each time log. Rows for the project you invoiced should be billed; rows for other projects should not. If those other rows are flagged billed too, and the paid invoice was raised via the Sales Workspace, you are seeing #44167.
Invoice from the Project instead
For a multi-project timesheet, create the Sales Invoice from each Project rather than via the Sales Workspace and Fetch Timesheet. The project-scoped route filters the time logs to that project, so it consumes and marks billed only that project's hours, leaving the others available to invoice.
Recover hours already locked
Where a timesheet is already fully flagged, don't cancel the legitimate invoice — that revenue is correct. Un-bill the wrongly flagged time logs (by editing the billed flag, or by cancelling and re-raising via the per-project route so the flags set correctly), then re-invoice the remaining projects from their own projects.
Reconcile the timesheet
Confirm that total invoiced hours across all the invoices equal the timesheet's billable hours. A shortfall means hours are still stranded. And after any Sales Invoice return or credit note, re-check the flags — returns don't reliably un-bill timesheets (#51131), so don't assume a credit note reset them.
When the biller isn't the person who logged the time
The consultant who logged hours across two projects has moved on to next week's work. The person raising invoices is in accounts, bills from the Sales Workspace because that's where invoices live, and has no reason to know that route behaves differently from invoicing via a project. The stranded hours surface only when someone tries to bill the second project and can't — often at month end, under time pressure, which is the worst moment to be untangling billed flags.
The fix is a billing convention, not a permission. Standardise on invoicing project work from the Project, document it for whoever raises invoices, and pair it with the structural choice — one timesheet per project where practical — so the safe path is also the default path. Add a month-end reconciliation that compares invoiced hours to logged billable hours per timesheet, and stranded hours surface as a variance instead of a client complaint.
Draft policy for your delivery and finance leads to ratify. Time on client projects is invoiced from the Project, not via the Sales Workspace, so a timesheet spanning projects cannot be marked fully billed by a single invoice. Where the process allows, one timesheet is logged per project. At month end, invoiced hours are reconciled against billable hours logged per timesheet, and any shortfall is investigated before the period closes. Billed flags are re-checked after any credit note, since returns do not reliably un-bill timesheets. Verify the behaviour on your ERPNext version before adopting this, as the underlying issue was reported on v15.41.1.
Invoice from the project, or split the timesheet
FAQ
+Why does ERPNext mark the whole timesheet billed when I invoice one project?
Because the invoice was raised via the Sales Workspace using Fetch Timesheet, which marks the entire timesheet billed rather than only the invoiced project's hours. Invoicing from the Project instead marks only that project's hours, leaving the others available. It's the behaviour in #44167.
+How do I invoice only one project's hours from a shared timesheet?
Create the Sales Invoice from the Project itself rather than from the Sales Workspace. The project-scoped route filters the time logs to that project, so only its billable hours are consumed and marked billed, and the other projects' hours stay available to invoice from their own projects.
+Which ERPNext version does this affect?
It was reported on ERPNext v15.41.1 with Frappe v15.47.1 in #44167, which is closed without a linked fix. Because there's no documented patch, verify the behaviour on your own instance with a two-project test timesheet rather than relying on a version number.
+How do I recover hours that were wrongly marked billed?
Don't cancel the correct invoice. Un-bill the wrongly flagged time logs — by editing the billed flag or by cancelling and re-raising via the per-project route so the flags set correctly — then re-invoice the remaining projects from their own projects. Reconcile total invoiced hours against the timesheet's billable hours afterwards.
+What happens if I don't fix it?
Real billable work becomes uninvoiceable — the hours are flagged as already charged when they weren't, so that revenue is stranded until you correct the flags. Across many multi-project timesheets it adds up to a meaningful gap between hours delivered and hours billed, which usually surfaces as a month-end shortfall nobody can immediately explain.
+Does cancelling the invoice un-bill the timesheet?
Not reliably. Sales Invoice returns and cancellations don't always reset the timesheet billed flags (#51131), so after any credit note you should re-check the flags on the affected time logs rather than assuming they reverted. Verify before re-invoicing.
Related issues you may also hit
- Sales Invoice returns not un-billing timesheets (#51131).
- ERPNext for IT and software companies — the project-billing model this sits inside.
- ERPNext HRMS attendance and leave — where time tracking meets payroll rather than billing.
- ERPNext GST return filing — where under-billed revenue shows up as a shortfall.
Closing
This is a routing problem wearing the costume of a bug: the same timesheet bills correctly from the project and incorrectly from the workspace. Standardise on invoicing project work from the project, keep one timesheet per project where you can, and reconcile invoiced hours against logged hours each month. Do that and the hours your team actually worked stay billable, instead of being locked away by the guard that was meant to protect them.
Billable hours going missing between the timesheet and the invoice?
We audit how your timesheets are billed, recover hours stranded by the wrong invoicing route, and set the project-billing workflow that keeps delivered work billable.