Okay .. worked it out.
We went through a process of dropping triggers until we narrowed it down to a single trigger that was causing the error. Turns out that there was something rather wrong with it - it seems that it's meant to be attached to a table, but isn't (i.e. it doesn't appear in the triggers list). So I'm guessing this minor corruption caused SqlPackage to fail.
In case anyone finds it useful, this is the script I used to drop ranges of triggers, which helped me find the culprit:
http://www.codeproject.com/Tips/662699/Drop-all-Triggers-belonging-to-any-schema-in-MS-SQ
Use ClaimsSqlPackageTest
DECLARE @SQLCmd nvarchar(1000)
DECLARE @Trig varchar(500)
DECLARE @sch varchar(500)
Declare @count int = 0
DECLARE TGCursor CURSOR FOR
SELECT ISNULL(tbl.name, vue.name) AS [schemaName]
, trg.name AS triggerName
FROM sys.triggers trg
LEFT OUTER JOIN (SELECT tparent.object_id, ts.name
FROM sys.tables tparent
INNER JOIN sys.schemas ts ON TS.schema_id = tparent.SCHEMA_ID)
AS tbl ON tbl.OBJECT_ID = trg.parent_id
LEFT OUTER JOIN (SELECT vparent.object_id, vs.name
FROM sys.views vparent
INNER JOIN sys.schemas vs ON vs.schema_id = vparent.SCHEMA_ID)
AS vue ON vue.OBJECT_ID = trg.parent_id
OPEN TGCursor
FETCH NEXT FROM TGCursor INTO @sch,@Trig
WHILE @@FETCH_STATUS = 0
BEGIN
SET @SQLCmd = N'DROP TRIGGER [' + @sch + '].[' + @Trig + ']'
If @count >= 155 AND @count <= 160 Begin
EXEC sp_executesql @SQLCmd
PRINT @SQLCmd
End
Set @count = @count + 1
FETCH next FROM TGCursor INTO @sch,@Trig
END
CLOSE TGCursor
DEALLOCATE TGCursor